[洛谷P3373] 线段树板子题

线段树区间修改,区间查询模板题
改了n次才过啊!!!
传送门
#include<bits/stdc++.h> using namespace std; #define MAX 100005 struct Node { int l,r; long long lazyadd,lazymul,val; }node[MAX<<2]; long long d[MAX],p; inline void pushup(int rt) { node[rt].val=(node[rt<<1].val+node[rt<<1|1].val)%p; } inline void construct(int rt,int l,int r) { node[rt].l=l; node[rt].r=r; node[rt].lazyadd=node[rt].val=0; node[rt].lazymul=1; if(l==r) { node[rt].val=d[l]; return; } int mid=(l+r)>>1; construct(rt<<1,l,mid); construct(rt<<1|1,mid+1,r); pushup(rt); } inline void pushdown(int rt) { if(node[rt].lazymul!=1) { node[rt<<1].val=(node[rt<<1].val%p)*(node[rt].lazymul%p)%p; node[rt<<1|1].val=(node[rt<<1|1].val%p)*(node[rt].lazymul%p)%p; node[rt<<1].lazymul=(node[rt<<1].lazymul%p)*(node[rt].lazymul%p)%p; node[rt<<1|1].lazymul=(node[rt<<1|1].lazymul%p)*(node[rt].lazymul%p)%p; node[rt<<1].lazyadd=(node[rt<<1].lazyadd)*(node[rt].lazymul)%p; node[rt<<1|1].lazyadd=(node[rt<<1|1].lazyadd)*(node[rt].lazymul)%p; node[rt].lazymul=1; } if(node[rt].lazyadd) { node[rt<<1].val+=(node[rt<<1].r-node[rt<<1].l+1)*node[rt].lazyadd; node[rt<<1|1].val+=(node[rt<<1|1].r-node[rt<<1|1].l+1)*node[rt].lazyadd; node[rt<<1].lazyadd+=node[rt].lazyadd; node[rt<<1|1].lazyadd+=node[rt].lazyadd; node[rt].lazyadd=0; } } inline void modify(int rt,int fr,int to,long long v) { if(fr<=node[rt].l&&to>=node[rt].r) { node[rt].lazyadd+=v; node[rt].val+=v*(node[rt].r-node[rt].l+1); return; } int mid=(node[rt].l+node[rt].r)>>1; pushdown(rt); if(fr<=mid) modify(rt<<1,fr,to,v); if(to>mid) modify(rt<<1|1,fr,to,v); pushup(rt); } inline void modify2(int rt,int fr,int to,long long v) { if(fr<=node[rt].l&&to>=node[rt].r) { node[rt].lazymul=(node[rt].lazymul*v)%p; node[rt].lazyadd=(node[rt].lazyadd*v)%p; node[rt].val=(v*node[rt].val)%p; return; } int mid=(node[rt].l+node[rt].r)>>1; pushdown(rt); if(fr<=mid) modify2(rt<<1,fr,to,v); if(to>mid) modify2(rt<<1|1,fr,to,v); pushup(rt); } inline long long query(int rt,int fr,int to,int l,int r) { if(fr<=l&&to>=r) return node[rt].val%p; pushdown(rt); int mid=(l+r)>>1; long long ans=0; if(fr<=mid) ans+=query(rt<<1,fr,to,l,mid); if(to>mid) ans+=query(rt<<1|1,fr,to,mid+1,r); return ans%p; } int main() { //freopen("in.txt","r",stdin); //freopen("testout.txt","w",stdout); long long n,m,a,b,c,k; scanf("%lld%lld%lld",&n,&m,&p); for(register int i=1;i<=n;++i) scanf("%lld",&d[i]),d[i]%=p; construct(1,1,n); for(register int i=1;i<=m;++i) { scanf("%lld%lld%lld",&a,&b,&c); if(a==2) { scanf("%lld",&k); modify(1,b,c,k%p); } else if(a==1) { scanf("%lld",&k); modify2(1,b,c,k%p); } else printf("%lld\n",query(1,b,c,1,n)); } return 0; }

更新乘法标记的时候顺便也要把加法标记更新啊!!!

我太菜了

猜你喜欢

转载自www.cnblogs.com/juruo-1237898456ye/p/11025330.html