BZOJ1798

来源:互联网 发布:绵阳广播电视网络 编辑:程序博客网 时间:2024/06/09 17:47

传送门:BZOJ1798

双状态的线段树,注意优先级。

#include <cstdio>#include <cstdlib>#include <iostream>#include <algorithm>#include <cstring>using namespace std;struct Node{    int ls,rs;    long long w;    long long add;    long long times;    Node(){        ls=rs=0;        w=0;        add=0;        times=1;    }};long long p;Node tree[200005];int y1,y2;int root,num;int da[100005];int m,n;void PushDown(int root){    tree[tree[root].ls].add=tree[tree[root].ls].add*tree[root].times+tree[root].add;    tree[tree[root].rs].add=tree[tree[root].rs].add*tree[root].times+tree[root].add;    tree[tree[root].ls].times*=tree[root].times;    tree[tree[root].rs].times*=tree[root].times;    tree[tree[root].ls].add%=p;    tree[tree[root].rs].add%=p;    tree[tree[root].ls].times%=p;    tree[tree[root].rs].times%=p;    tree[root].times=1;tree[root].add=0;}void Maintain(int root,int l,int r){    tree[root].w=tree[tree[root].ls].w+tree[tree[root].rs].w;    tree[root].w*=tree[root].times;    tree[root].w+=(r-l+1)*tree[root].add;    tree[root].w%=p;}void Update(int root,int l,int r,int addv,int timesv){    if(y1<=l&&r<=y2){        if(addv!=-1)            tree[root].add+=addv;        else{            tree[root].add*=timesv;            tree[root].times*=timesv;        }        tree[root].add%=p;        tree[root].times%=p;    }    else{        PushDown(root);        int mid=(l+r)/2;        if(y1<=mid)            Update(tree[root].ls,l,mid,addv,timesv);        else            Maintain(tree[root].ls,l,mid);        if(mid<y2)            Update(tree[root].rs,mid+1,r,addv,timesv);        else            Maintain(tree[root].rs,mid+1,r);    }    Maintain(root,l,r);}long long Query(int root,int l,int r){    if(y1<=l&&r<=y2)        return tree[root].w%p;    int mid=(l+r)/2;    PushDown(root);    Maintain(tree[root].ls,l,mid);    Maintain(tree[root].rs,mid+1,r);    Maintain(root,l,r);    long long ans=0;    if(y1<=mid)        ans+=Query(tree[root].ls,l,mid);    if(mid<y2)        ans+=Query(tree[root].rs,mid+1,r);    return ans%p;}void MakeTree(int&root,int l,int r){    root=++num;    if(l==r)        return;    int mid=(l+r)/2;    MakeTree(tree[root].ls,l,mid);    MakeTree(tree[root].rs,mid+1,r);}void Readdata(){    scanf("%d",&n);    cin>>p;    for(int i=1;i<=n;i++)        scanf("%d",&da[i]);}void Solve(){    for(int i=1;i<=n;i++){        y1=y2=i;        Update(root,1,n,da[i],1);    }    scanf("%d",&m);    for(int i=1;i<=m;i++){        int a,t,g,c;        scanf("%d",&a);        if(a==1){            scanf("%d%d%d",&y1,&y2,&c);            Update(root,1,n,-1,c);        }        if(a==2){            scanf("%d%d%d",&y1,&y2,&c);            Update(root,1,n,c,1);        }        if(a==3){            scanf("%d%d",&y1,&y2);            printf("%lld\n",Query(root,1,n));        }    }}int main(){    Readdata();    MakeTree(root,1,n);    Solve();    return 0;}
0 0
原创粉丝点击