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
| #include <bits/stdc++.h> #define int long long using namespace std; const int N=100010; struct node{ int l,r; int sum,add,mul; }tr[N*4+10]; int a[N]; int n,p,m; inline void pushup(int x){ tr[x].sum=(tr[2*x].sum+tr[2*x+1].sum)%p; } inline void eval(int x,int add,int mul){
tr[x].sum=(tr[x].sum*mul+add*(tr[x].r-tr[x].l+1))%p; tr[x].mul=(mul*tr[x].mul)%p; tr[x].add=(tr[x].add*mul+add)%p; }
inline void pushdown(int x){ eval(x*2,tr[x].add,tr[x].mul); eval(x*2+1,tr[x].add,tr[x].mul); tr[x].add=0,tr[x].mul=1; } void build(int x,int l,int r){ tr[x].l=l,tr[x].r=r; tr[x].add=0,tr[x].mul=1; if(l==r){ tr[x].sum=a[l]; return; } int mid=(l+r)/2; build(x*2,l,mid),build(x*2+1,mid+1,r); pushup(x); } void change(int x,int l,int r,int add,int mul){ if(l<=tr[x].l&&r>=tr[x].r) eval(x,add,mul); else{ pushdown(x); int mid=(tr[x].l+tr[x].r)/2; if(l<=mid) change(x*2,l,r,add,mul); if(r>mid) change(x*2+1,l,r,add,mul); pushup(x); } } int query(int x,int l,int r){ if(l<=tr[x].l&&r>=tr[x].r) return tr[x].sum; int sum=0; pushdown(x); int mid=(tr[x].l+tr[x].r)/2; if(l<=mid) sum+=query(x*2,l,r)%p; if(r>mid) sum+=query(x*2+1,l,r)%p; return sum; } signed main(){ int t,g,c,ch; cin>>n>>p; for(int i=1;i<=n;i++) cin>>a[i]; build(1,1,n); cin>>m; while(m--){ cin>>ch>>t>>g; if(ch==1){ cin>>c; change(1,t,g,0,c); } else if(ch==2){ cin>>c; change(1,t,g,c,1); } else cout<<query(1,t,g)%p<<endl; } return 0; }
|