【传送门:BZOJ5039】
简要题意:
给出一个长度为n个序列,有m个操作,共为三种操作:
1 x y c表示将x到y的值全部*c
2 x y c表示将x到y的值全部+c
3 x y求x到y的值的和
题解:
参考代码:
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; struct node { int l,r,lc,rc; LL c,lazyc,lazyj; }tr[210000];int len; LL a[110000]; LL Mod; void update(int now) { int lc=tr[now].lc,rc=tr[now].rc; LL j=tr[now].lazyj,c=tr[now].lazyc; if(lc!=-1) { tr[lc].c=(LL(tr[lc].r-tr[lc].l+1)*j%Mod+(c*tr[lc].c)%Mod)%Mod; tr[lc].lazyc=(tr[lc].lazyc*c)%Mod; tr[lc].lazyj=((tr[lc].lazyj*c)%Mod+j)%Mod; } if(rc!=-1) { tr[rc].c=(LL(tr[rc].r-tr[rc].l+1)*j%Mod+(c*tr[rc].c)%Mod)%Mod; tr[rc].lazyc=(tr[rc].lazyc*c)%Mod; tr[rc].lazyj=((tr[rc].lazyj*c)%Mod+j)%Mod; } tr[now].lazyc=1;tr[now].lazyj=0; } void bt(int l,int r) { len++;int now=len; tr[now].l=l;tr[now].r=r;tr[now].c=0; tr[now].lc=tr[now].rc=-1; tr[now].lazyc=1;tr[now].lazyj=0; if(l<r) { int mid=(l+r)/2; tr[now].lc=len+1;bt(l,mid); tr[now].rc=len+1;bt(mid+1,r); } } void cheng(int now,int l,int r,LL c) { if(tr[now].l==l&&tr[now].r==r) { tr[now].c=(tr[now].c*c)%Mod; tr[now].lazyc=(tr[now].lazyc*c)%Mod; tr[now].lazyj=(tr[now].lazyj*c)%Mod; return ; } int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2; if(tr[now].lazyc!=1||tr[now].lazyj!=0) update(now); if(r<=mid) cheng(lc,l,r,c); else if(l>mid) cheng(rc,l,r,c); else cheng(lc,l,mid,c),cheng(rc,mid+1,r,c); tr[now].c=(tr[lc].c+tr[rc].c)%Mod; } void jia(int now,int l,int r,LL c) { if(tr[now].l==l&&tr[now].r==r) { tr[now].c=(tr[now].c+LL(r-l+1)%Mod*c)%Mod; tr[now].lazyj=(tr[now].lazyj+c)%Mod; return ; } int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2; if(tr[now].lazyc!=1||tr[now].lazyj!=0) update(now); if(r<=mid) jia(lc,l,r,c); else if(l>mid) jia(rc,l,r,c); else jia(lc,l,mid,c),jia(rc,mid+1,r,c); tr[now].c=(tr[lc].c+tr[rc].c)%Mod; } LL qiuhe(int now,int l,int r) { if(tr[now].l==l&&tr[now].r==r) return tr[now].c; int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2; if(tr[now].lazyc!=1||tr[now].lazyj!=0) update(now); if(r<=mid) return qiuhe(lc,l,r); else if(l>mid) return qiuhe(rc,l,r); else return (qiuhe(lc,l,mid)+qiuhe(rc,mid+1,r))%Mod; } int main() { int n; scanf("%d%lld",&n,&Mod); len=0;bt(1,n); for(int i=1;i<=n;i++) scanf("%lld",&a[i]),jia(1,i,i,a[i]); int m; scanf("%d",&m); for(int i=1;i<=m;i++) { int t; scanf("%d",&t); if(t==1) { int x,y;LL c; scanf("%d%d%lld",&x,&y,&c); cheng(1,x,y,c%Mod); } if(t==2) { int x,y;LL c; scanf("%d%d%lld",&x,&y,&c); jia(1,x,y,c%Mod); } if(t==3) { int x,y; scanf("%d%d",&x,&y); printf("%lld ",qiuhe(1,x,y)); } } return 0; }