1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
| #include<iostream> #include<cstdio> #define MAX 100010 using namespace std; typedef unsigned long long ll; struct Node { int l,r; ll value; ll add,time; }; Node tr[MAX<<2]= {0}; ll aa[MAX]= {0}; ll N,M,P; ll Read() { ll x=0,f=1; char c=getchar(); while(c<'0'||c>'9') { if(c=='-')f=-1; c=getchar(); } while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar(); return x*f; }
void build(int i,int l,int r) { tr[i].l=l,tr[i].r=r,tr[i].value=0,tr[i].time=1; if(l==r) { tr[i].value=aa[l]; return; } build(i<<1,l,(l+r)>>1); build(i<<1|1,((l+r)>>1)+1,r); tr[i].value=tr[i<<1].value+tr[i<<1|1].value; }
void pushdown(int i) { if(tr[i].add==0&&tr[i].time==1) return; if( tr[i].l==tr[i].r ) { tr[i].add=0; tr[i].time=1; return; } tr[i<<1].value=(tr[i<<1].value*tr[i].time+tr[i].add*(tr[i<<1].r-tr[i<<1].l+1))%P; tr[i<<1|1].value=(tr[i<<1|1].value*tr[i].time+tr[i].add*(tr[i<<1|1].r-tr[i<<1|1].l+1))%P; tr[i<<1].time=tr[i<<1].time*tr[i].time%P; tr[i<<1].add=(tr[i<<1].add*tr[i].time+tr[i].add)%P; tr[i<<1|1].time=tr[i<<1|1].time*tr[i].time%P; tr[i<<1|1].add=(tr[i<<1|1].add*tr[i].time+tr[i].add)%P; tr[i].add=0; tr[i].time=1; }
ll query(int i,int l,int r) { if(l<=tr[i].l&&r>=tr[i].r) { return tr[i].value; } if(l>tr[i].r||r<tr[i].l) return 0; pushdown(i); return (query(i<<1,l,r)+query(i<<1|1,l,r)); }
void updateadd(int i,int l,int r,int k) { pushdown(i); if(l<=tr[i].l&&r>=tr[i].r) { tr[i].value+=(tr[i].r-tr[i].l+1)*k%P; tr[i].add=k%P; return; } if(r<tr[i].l||l>tr[i].r) { return; } updateadd(i<<1,l,r,k); updateadd(i<<1|1,l,r,k); tr[i].value=(tr[i<<1].value+tr[i<<1|1].value)%P; return; }
void updatetime(int i,int l,int r,int k) { pushdown(i); if(l<=tr[i].l&&r>=tr[i].r) { tr[i].value=tr[i].value*k%P; tr[i].time=k%P; return; } if(r<tr[i].l||l>tr[i].r) { return; } updatetime(i<<1,l,r,k); updatetime(i<<1|1,l,r,k); tr[i].value=(tr[i<<1].value+tr[i<<1|1].value)%P; return; } int main() { int i; int o,a,b,k; N=Read(),M=Read(),P=Read(); for(i=1; i<=N; i++) aa[i]=Read(); build(1,1,N); while(M--) { o=Read(),a=Read(),b=Read(); if(o==1) { k=Read(); updatetime(1,a,b,k); } if(o==2) { k=Read(); updateadd(1,a,b,k); } if(o==3) { printf("%lld\n",query(1,a,b)%P); } } return 0; }
|