BZOJ 3932: [CQOI2015]任务查询系统

来源:互联网 发布:ubuntu防火墙在哪里 编辑:程序博客网 时间:2024/06/12 00:40

一道可持久化线段树裸题,搞出来每一个位置的权值线段树然后正常查找就行了。

#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<iostream>#include<iomanip>#include<ctime>#include<cmath>#include<algorithm>using namespace std;struct xianduan{    xianduan *ls,*rs;    int size;    long long sum;    void *operator new(size_t,xianduan *_,xianduan *__,int ___,long long ____)    {        static xianduan *C,*mempool;        if(C==mempool) mempool=(C=new xianduan[1<<15])+(1<<15);        C->ls=_;        C->rs=__;        C->size=___;        C->sum=____;        return C++;    }    friend xianduan* maketree(xianduan *o,int l,int r,int pos,int c_size,long long c_sum)    {        int mid=l+r>>1;        if(l==r) return new(0x0,0x0,o->size+c_size,o->sum+c_sum)xianduan;        if(pos<=mid) return new(maketree(o->ls,l,mid,pos,c_size,c_sum),o->rs,o->size+c_size,o->sum+c_sum)xianduan;        else return new(o->ls,maketree(o->rs,mid+1,r,pos,c_size,c_sum),o->size+c_size,o->sum+c_sum)xianduan;    }    friend long long query(xianduan *o,int l,int r,int k)    {        int mid=l+r>>1;        if(l==r) return k*l;        if(o->ls->size>=k) return query(o->ls,l,mid,k);        else return query(o->rs,mid+1,r,k-o->ls->size)+o->ls->sum;    }}*root[10000011];struct change{    int pos;    int tim,lei;    long long ying;    bool operator <(change b) const    {        return tim<b.tim;    }}changes[200020];int top=0;int main(){    int n,m;    scanf("%d%d",&n,&m);    int maxx=0;    for(int i=1;i<=n;i++)    {        int x,y,v;        scanf("%d%d%d",&x,&y,&v);        if(x>maxx) maxx=x;        if(y+1>maxx) maxx=y+1;        changes[++top].tim=x;        changes[top].pos=v;        changes[top].lei=1;        changes[top].ying=v;        changes[++top].tim=y+1;        changes[top].pos=v;        changes[top].lei=-1;        changes[top].ying=-v;    }    sort(changes+1,changes+1+top);    int wz=1;    root[0]=new(0x0,0x0,0,0ll)xianduan;    root[0]->ls=root[0]->rs=root[0];    for(int i=1;i<=m;i++)    {        root[i]=root[i-1];        while(changes[wz].tim==i)        {            root[i]=maketree(root[i],1,10000000,changes[wz].pos,changes[wz].lei,changes[wz].ying);            wz++;        }    }    long long ans=1;    for(int i=1;i<=m;i++)    {        int x,aa,bb,cc;        scanf("%d%d%d%d",&x,&aa,&bb,&cc);        int k=1+(aa*ans+bb)%cc;        if(k>root[x]->size) k=root[x]->size;        ans=query(root[x],1,10000000,k);        printf("%lld\n",ans);    }    return 0;}
0 0
原创粉丝点击