洛谷 P3373 【模板】线段树 2

匿名 (未验证) 提交于 2019-12-02 23:48:02

Ŀ¼


˼·

乘法优先(说了和没说一样,qwq)

$Code$

#include<iostream> #include<cstring> #include<cstdio> #include<string> #include<algorithm> #define LL long long #define MAXN 100001 using namespace std; LL n,m,mod; struct node{     LL l,r,w,mul,add; }tree[MAXN*4]; inline LL read(){     LL x=0;bool f=0;char c=getchar();     while(c<'0'||c>'9'){if(c=='-')f=!f;c=getchar();}     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}     return f?-x:x; } void pushdown(LL now){     if(tree[now].l==tree[now].r) return;     tree[now<<1].w=(tree[now<<1].w*tree[now].mul+tree[now].add*(tree[now<<1].r-tree[now<<1].l+1))%mod;     tree[now<<1|1].w=(tree[now<<1|1].w*tree[now].mul+tree[now].add*(tree[now<<1|1].r-tree[now<<1|1].l+1))%mod;     tree[now<<1].mul=(tree[now].mul*tree[now<<1].mul)%mod;     tree[now<<1|1].mul=(tree[now].mul*tree[now<<1|1].mul)%mod;     tree[now<<1].add=(tree[now<<1].add*tree[now].mul+tree[now].add)%mod;     tree[now<<1|1].add=(tree[now<<1|1].add*tree[now].mul+tree[now].add)%mod;     tree[now].mul=1,tree[now].add=0;     return; } void build(LL l,LL r,LL now){     tree[now].mul=1;     tree[now].l=l;tree[now].r=r;     if(tree[now].l==tree[now].r){         tree[now].w=read();         return;     }     LL mid=(tree[now].l+tree[now].r)>>1;     build(l,mid,now<<1);build(mid+1,r,now<<1|1);     tree[now].w=tree[now<<1].w+tree[now<<1|1].w;     tree[now].w%=mod; } void update_rmul(LL x,LL y,LL k,LL now){     if(y<tree[now].l||x>tree[now].r) return;     if(tree[now].l>=x&&tree[now].r<=y){         tree[now].w=(tree[now].w*k)%mod;         tree[now].mul=(tree[now].mul*k)%mod;         tree[now].add=(tree[now].add*k)%mod;         return;     }     pushdown(now);     update_rmul(x,y,k,now<<1);update_rmul(x,y,k,now<<1|1);     tree[now].w=(tree[now<<1].w+tree[now<<1|1].w)%mod; } void update_radd(LL x,LL y,LL k,LL now){     if(y<tree[now].l||x>tree[now].r) return;     if(tree[now].l>=x&&tree[now].r<=y){         tree[now].add=(tree[now].add+k)%mod;         tree[now].w=(tree[now].w+(tree[now].r-tree[now].l+1)*k)%mod;         return;     }     pushdown(now);     update_radd(x,y,k,now<<1);update_radd(x,y,k,now<<1|1);     tree[now].w=(tree[now<<1].w+tree[now<<1|1].w)%mod; } LL ask_range(LL x,LL y,LL now){     if(y<tree[now].l||x>tree[now].r) return 0;     if(tree[now].l>=x&&tree[now].r<=y) return tree[now].w;     pushdown(now);     return (ask_range(x,y,now<<1)+ask_range(x,y,now<<1|1))%mod; }  int main(){     n=read(),m=read(),mod=read();     build(1,n,1);     LL bz,x,y,k;     while(m--){         bz=read(),x=read(),y=read();         if(bz==1){             k=read();             update_rmul(x,y,k,1);         }         if(bz==2){             k=read();             update_radd(x,y,k,1);         }         if(bz==3){             printf("%lld\n",ask_range(x,y,1)%mod);         }     }     return 0; }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!