注意一个细节,查询和更新都需要pushdown();
#include <bits/stdc++.h> #define int long long using namespace std; int n,m,p; int a[1000010]; struct ha{ long long v; long long mul; long long add; }tree[1000010]; void build(int k,int l,int r) { tree[k].mul=1; tree[k].add=0; if(l==r){ tree[k].v=a[l]; } else{ int mid=(l+r)/2; build(k<<1,l,mid); build(k<<1|1,mid+1,r); tree[k].v=tree[k<<1].v+tree[k<<1|1].v; } tree[k].v%=p; return; } void pushdown(int k,int l,int r) { int mid=(l+r)/2; tree[k<<1].v=(tree[k<<1].v*tree[k].mul+tree[k].add*(mid-l+1))%p; tree[k<<1|1].v=(tree[k<<1|1].v*tree[k].mul+tree[k].add*(r-mid))%p; tree[k<<1].mul=(tree[k<<1].mul*tree[k].mul)%p; tree[k<<1|1].mul=(tree[k<<1|1].mul*tree[k].mul)%p; tree[k<<1].add=(tree[k<<1].add*tree[k].mul+tree[k].add)%p; tree[k<<1|1].add=(tree[k<<1|1].add*tree[k].mul+tree[k].add)%p; tree[k].mul=1; tree[k].add=0; return; } void muladd(int k,int l,int r,int x,int y,int goal) { if(y<l||x>r){ return; } if(x<=l&&r<=y){ tree[k].v=(tree[k].v*goal)%p; tree[k].mul=(tree[k].mul*goal)%p; tree[k].add=(tree[k].add*goal)%p; return; } pushdown(k,l,r); int mid=(l+r)/2; muladd(k<<1,l,mid,x,y,goal); muladd(k<<1|1,mid+1,r,x,y,goal); tree[k].v=(tree[k<<1].v+tree[k<<1|1].v)%p; return; } void addadd(int k,int l,int r,int x,int y,int goal) { if(x>r||y<l){ return; } if(x<=l&&y>=r){ tree[k].add=(tree[k].add+goal)%p; tree[k].v=(tree[k].v+goal*(r-l+1))%p; return; } pushdown(k,l,r); int mid=(l+r)/2; addadd(k<<1,l,mid,x,y,goal); addadd(k<<1|1,mid+1,r,x,y,goal); tree[k].v=(tree[k<<1].v+tree[k<<1|1].v)%p; return; } int ask(int k,int l,int r,int x,int y) { if(x>r||y<l){ return 0; } if(x<=l&&y>=r){ return tree[k].v; } pushdown(k,l,r); int mid=(l+r)/2; return (ask(k<<1,l,mid,x,y)+ask(k<<1|1,mid+1,r,x,y))%p; } signed main() { cin>>n>>p; for(int i=1;i<=n;i++){ cin>>a[i]; } build(1,1,n); cin>>m; for(int i=1;i<=m;i++){ int type; cin>>type; if(type==1){ int x,y,v; cin>>x>>y>>v; muladd(1,1,n,x,y,v); } else if(type==2){ int x,y,v; cin>>x>>y>>v; addadd(1,1,n,x,y,v); } else{ int x,y; cin>>x>>y; cout<<ask(1,1,n,x,y)<<endl; } } }