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
| #include<bits/stdc++.h> using namespace std; const int N=1e5+8; long long n,m,p; long long a[N]; struct Segtreemode{ long long val; long long mul; long long add; }segtree[N<<2]; void pushup(int rt){ segtree[rt].val=(segtree[rt<<1].val+segtree[rt<<1|1].val)%p; } void pushdown(int l,int r,int rt){ int mid=(l+r)/2; segtree[rt<<1].val=(segtree[rt<<1].val*segtree[rt].mul+(mid-l+1)*segtree[rt].add)%p; segtree[rt<<1].mul=(segtree[rt].mul*segtree[rt<<1].mul)%p; segtree[rt<<1].add=(segtree[rt].add+segtree[rt].mul*segtree[rt<<1].add)%p; segtree[rt<<1|1].val=(segtree[rt<<1|1].val*segtree[rt].mul+(r-mid)*segtree[rt].add)%p; segtree[rt<<1|1].mul=(segtree[rt].mul*segtree[rt<<1|1].mul)%p; segtree[rt<<1|1].add=(segtree[rt].add+segtree[rt].mul*segtree[rt<<1|1].add)%p; segtree[rt].mul=1; segtree[rt].add=0; } void build(int l,int r,int rt){ segtree[rt].mul=1; segtree[rt].add=0; if(l==r){ segtree[rt].val=a[l]%p; return ; } else{ int mid=(l+r)/2; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); pushup(rt); } } void update_mul(int l1,int r1,long long c,int l,int r,int rt){ if(l>=l1&&r<=r1){ segtree[rt].val =(segtree[rt].val*c)%p; segtree[rt].mul=(segtree[rt].mul*c)%p; segtree[rt].add=(segtree[rt].add*c)%p; return ; } else if(l>r1||r<l1)return ; int mid=(l+r)/2; pushdown(l,r,rt); update_mul(l1,r1,c,l,mid,rt<<1); update_mul(l1,r1,c,mid+1,r,rt<<1|1); pushup(rt); } void update_add(int l1,int r1,long long c,int l,int r,int rt){ if(l>=l1&&r<=r1){ segtree[rt].val=(c*(r-l+1)+segtree[rt].val)%p; segtree[rt].add=(segtree[rt].add+c)%p; return ; } else if(l>r1||r<l1)return ; int mid=(l+r)/2; pushdown(l,r,rt); update_add(l1,r1,c,l,mid,rt<<1); update_add(l1,r1,c,mid+1,r,rt<<1|1); pushup(rt); } long long query(int l1,int r1,int l,int r,int rt){ if(l>=l1&&r<=r1){ return segtree[rt].val; } else if(l>r1||r<l1)return 0; int mid=(l+r)/2; pushdown(l,r,rt); return (query(l1,r1,l,mid,rt<<1)+query(l1,r1,mid+1,r,rt<<1|1))%p; } int main(){ scanf("%d%d%lld",&n,&m,&p); for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); } build(1,n,1); while(m--){ int id=0; scanf("%d",&id); if(id==1){ long long x,y,k; scanf("%d%d%lld",&x,&y,&k); update_mul(x,y,k,1,n,1); } else if(id==2){ long long x,y,k; scanf("%d%d%lld",&x,&y,&k); update_add(x,y,k,1,n,1); } else{ int x,y; scanf("%d%d",&x,&y); printf("%lld\n",query(x,y,1,n,1)); } } return 0; }
|