线段树区间乘法+区间加法

来源:互联网 发布:抗韩中年人淘宝外设店 编辑:程序博客网 时间:2024/05/17 06:57
/*    线段树区间乘法+区间加法    by sbn*/#include<iostream>#include<cstdio>using namespace std;typedef long long ll;ll n,m,p,z;ll arr[100001];struct node{        ll l,r;        ll sum,add,mul;} tree[400001];void pushup(int o){        tree[o].sum=tree[o*2].sum+tree[o*2+1].sum;        tree[o].sum%=p;}inline void add_node(int root,ll num){    tree[root].add=(tree[root].add+num)%p;    tree[root].sum=(tree[root].sum+num*(tree[root].r-tree[root].l+1)%p)%p;}inline void mul_node(int root,ll num){    tree[root].mul=(tree[root].mul*num)%p;    tree[root].sum=(tree[root].sum*num)%p;    tree[root].add=(tree[root].add*num)%p;}void pushdown(ll root){    ll mid; mid=(tree[root].l+tree[root].r)/2;    if (tree[root].mul!=1)        {       mul_node(root*2,tree[root].mul);                mul_node(root*2+1,tree[root].mul);                tree[root].mul=1;        }       if (tree[root].add){                add_node(root*2,tree[root].add);                add_node(root*2+1,tree[root].add);                tree[root].add=0;        }        return;}void jia(int dl,int dr,int root,ll num){    if (tree[root].l>=dl&&tree[root].r<=dr){            tree[root].add+=num;            tree[root].add%=p;            tree[root].sum+=num*(dr-dl+1);            tree[root].sum%=p;            return;        }        pushdown(root);        ll mid=(tree[root].l+tree[root].r)/2;        if (dr<=mid)    jia(dl,dr,root*2,num);        else if (dl>mid)    jia(dl,dr,root*2+1,num);        else {jia(dl,mid,root*2,num);jia(mid+1,dr,root*2+1,num);}        pushup(root);}       void cheng(int dl,int dr,int root,ll num){        if (tree[root].l==dl&&tree[root].r==dr){                tree[root].add*=num;                tree[root].add%=p;                tree[root].sum*=num;                tree[root].sum%=p;                tree[root].mul*=num;                tree[root].mul%=p;                return;        }        pushdown(root);        ll mid=(tree[root].l+tree[root].r)/2;        if (dr<=mid)    cheng(dl,dr,root*2,num);else        if (dl>mid) cheng(dl,dr,root*2+1,num);        else    {        cheng(dl,mid,root*2,num);cheng(mid+1,dr,root*2+1,num);}        pushup(root);        return;}inline ll getsum(int dl,int dr,int root){        if (tree[root].l>=dl&&tree[root].r<=dr){                return tree[root].sum%p;        }        pushdown(root);        ll mid=(tree[root].l+tree[root].r)/2;        if (dr<=mid)    return getsum(dl,dr,root*2)%p;        else if (dl>mid) return getsum(dl,dr,root*2+1)%p;        else return (getsum(dl,dr,root*2)+getsum(dl,dr,root*2+1))%p;}void build(int root,int x,int y){    //cout<<root<<" "<<x<<" "<<y<<endl;        tree[root].l=x;tree[root].r=y;tree[root].mul=1;tree[root].add=0;        if (x==y){            tree[root].sum=arr[x];            return;        }        build(root<<1,x,(x+y)/2);        build(root<<1|1,(x+y)/2+1,y);        pushup(root);}int main(){        //freopen("xianduanshu.in","r",stdin);        cin>>n>>m>>p;        for(int i=1;i<=n;i++)            cin>>arr[i];        build(1,1,n);        //for (int i=1;i<=2*n;i++)  cout<<tree[i].l<<" "<<tree[i].r<<" "<<tree[i].sum<<endl;            for (int i=1;i<=m;i++){            int a;            cin>>a;            if (a==1){                ll st,ed,v;                cin>>st>>ed>>v;                cheng(st,ed,1,v);            }            if (a==2){                ll st,ed,v;                cin>>st>>ed>>v;                jia(st,ed,1,v);                //for (int i=1;i<=2*n;i++)  cout<<tree[i].l<<" "<<tree[i].r<<" "<<tree[i].sum<<endl;            }            if (a==3){                ll st,ed;                cin>>st>>ed;                cout<<getsum(st,ed,1)%p<<endl;            }        }        return 0;}
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 瓦格纳 新款尼桑轩逸报价 多宝莱 途观2016款报价及图片 仙界传 600ml madison 芯片 天降 得宝莱 prado 电子设备 日产新车 momentum omni 逸动价格 grand 裤衩 耳放 血崩 mou 概念车 2019款速腾 总裁前妻 宝莱价格 经典 大众新帕萨特 眼疾手快 boys kayano fisher 天价妈咪爹地闪开宝宝来 宝柏 宝树 宝树作品 大汉王朝 宝树 时间之墟 宝树 黄金宝树 多宝树 孙宝树 煌宝树