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 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
struct Tree { int l,r; ll sum; ll lazyadd,lazymul; }tree[4*MAX]; int a[MAX]; int P;
void bulid(int pos,int l,int r) { tree[pos].l = l; tree[pos].r = r; if(l == r) { tree[pos].sum = a[l]; tree[pos].lazymul = 1; return; } int mid = (l+r)>>1; bulid(pos<<1,l,mid); bulid(pos<<1|1,mid+1,r); tree[pos].sum = tree[pos<<1].sum + tree[pos<<1|1].sum; tree[pos].lazymul = 1; }
void pushdown(int pos) { tree[pos<<1].sum = (tree[pos<<1].sum * tree[pos].lazymul) % P; tree[pos<<1|1].sum = (tree[pos<<1|1].sum * tree[pos].lazymul) % P; tree[pos<<1].sum = (tree[pos<<1].sum + tree[pos].lazyadd*(tree[pos<<1].r - tree[pos<<1].l + 1)) % P; tree[pos<<1|1].sum = (tree[pos<<1|1].sum + tree[pos].lazyadd*(tree[pos<<1|1].r - tree[pos<<1|1].l + 1)) % P;
tree[pos<<1].lazyadd = (tree[pos<<1].lazyadd*tree[pos].lazymul) % P; tree[pos<<1|1].lazyadd = (tree[pos<<1|1].lazyadd*tree[pos].lazymul) % P; tree[pos<<1].lazymul = (tree[pos<<1].lazymul*tree[pos].lazymul) % P; tree[pos<<1|1].lazymul = (tree[pos<<1|1].lazymul*tree[pos].lazymul) % P; tree[pos<<1].lazyadd = (tree[pos<<1].lazyadd + tree[pos].lazyadd ) % P; tree[pos<<1|1].lazyadd = (tree[pos<<1|1].lazyadd + tree[pos].lazyadd ) % P;
tree[pos].lazyadd = 0; tree[pos].lazymul = 1; }
void updateadd(int pos,int l,int r,int x) { if(l <= tree[pos].l && r >= tree[pos].r) { tree[pos].sum = (tree[pos].sum + (ll)x * (tree[pos].r - tree[pos].l + 1)) % P; tree[pos].lazyadd = (tree[pos].lazyadd + x) % P; return; } if(tree[pos].lazyadd || tree[pos].lazymul != 1) pushdown(pos); int mid = (tree[pos].l + tree[pos].r) >> 1; if(l <= mid) updateadd(pos<<1,l,r,x); if(r > mid) updateadd(pos<<1|1,l,r,x); tree[pos].sum = (tree[pos<<1].sum + tree[pos<<1|1].sum) % P; }
void updatemult(int pos,int l,int r,int x) { if(l <= tree[pos].l && r >= tree[pos].r) { tree[pos].sum = ((ll)x * tree[pos].sum) % P; tree[pos].lazymul = (tree[pos].lazymul*x) % P; tree[pos].lazyadd = (tree[pos].lazyadd*x) % P; return; } if(tree[pos].lazyadd || tree[pos].lazymul != 1) pushdown(pos); int mid = (tree[pos].l + tree[pos].r) >> 1; if(l <= mid) updatemult(pos<<1,l,r,x); if(r > mid) updatemult(pos<<1|1,l,r,x); tree[pos].sum = (tree[pos<<1].sum + tree[pos<<1|1].sum) % P; }
ll query(int pos,int l,int r) { if(l <= tree[pos].l && r >= tree[pos].r) { return tree[pos].sum; } if(tree[pos].lazyadd || tree[pos].lazymul != 1) pushdown(pos); int mid = (tree[pos].l + tree[pos].r) >> 1; ll ans = 0; if(l <= mid) ans += query(pos<<1,l,r); ans %= P; if(r > mid) ans += query(pos<<1|1,l,r); ans %= P; return ans; }
int main() { std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> N >> M >> P; for(int i = 1;i <= N;i++) { cin >> a[i]; } bulid(1,1,N); int x,y,z; while(M--) { cin >> x; if(x == 1) { cin >> x >> y >> z; updatemult(1,x,y,z); } else if(x == 2) { cin >> x >> y >> z; updateadd(1,x,y,z); } else if(x == 3) { cin >> x >> y; cout << query(1,x,y) <<endl; } } return 0; }
|