原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798
线段树区间更新:
1. 区间同同时加上一个数 2. 区间同时乘以一个数
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstdio> 5 #define lc root<<1 6 #define rc root<<1|1 7 typedef unsigned long long ull; 8 const int Max_N = 100010; 9 int Mod; 10 struct Node { 11 ull sum, add, mul; 12 }; 13 struct SegTree { 14 Node seg[Max_N << 2]; 15 inline void push_up(int root) { 16 seg[root].sum = (seg[lc].sum + seg[rc].sum) % Mod; 17 } 18 inline void built(int root, int l, int r) { 19 seg[root].add = 0, seg[root].mul = 1; 20 if (l == r) { 21 scanf("%lld", &seg[root].sum); 22 seg[root].sum %= Mod; 23 return; 24 } 25 int mid = (l + r) >> 1; 26 built(lc, l, mid); 27 built(rc, mid + 1, r); 28 push_up(root); 29 } 30 inline void push_down(int root, int len) { 31 if (seg[root].add != 0 || seg[root].mul != 1) { 32 ull &_add = seg[root].add, &_mul = seg[root].mul; 33 seg[lc].sum = (seg[lc].sum * _mul + (len - (len >> 1)) * _add) % Mod; 34 seg[lc].mul = (seg[lc].mul * _mul) % Mod; 35 seg[lc].add = (seg[lc].add * _mul + _add) % Mod; 36 seg[rc].sum = (seg[rc].sum * _mul + (len >> 1) * _add) % Mod; 37 seg[rc].mul = (seg[rc].mul * _mul) % Mod; 38 seg[rc].add = (seg[rc].add * _mul + _add) % Mod; 39 _add = 0, _mul = 1; 40 } 41 } 42 inline void update(int root, int l, int r, int x, int y, ull val, ull mul) { 43 if (x > r || y < l) return; 44 if (x <= l && y >= r) { 45 seg[root].add = (seg[root].add * mul + val) % Mod; 46 seg[root].mul = (seg[root].mul * mul) % Mod; 47 seg[root].sum = (seg[root].sum * mul + val * (r - l + 1)) % Mod; 48 return; 49 } 50 push_down(root, r - l + 1); 51 int mid = (l + r) >> 1; 52 update(lc, l, mid, x, y, val, mul); 53 update(rc, mid + 1, r, x, y, val, mul); 54 push_up(root); 55 } 56 inline ull query(int root, int l, int r, int x, int y) { 57 if (x > r || y < l) return 0; 58 if (x <= l && y >= r) { 59 return seg[root].sum; 60 } 61 push_down(root, r - l + 1); 62 ull ret = 0; 63 int mid = (l + r) >> 1; 64 ret += query(lc, l, mid, x, y); 65 ret += query(rc, mid + 1, r, x, y); 66 return ret %= Mod; 67 } 68 }seg; 69 int main() { 70 #ifdef LOCAL 71 freopen("in.txt", "r", stdin); 72 freopen("out.txt", "w+", stdout); 73 #endif 74 int n, m, a, b, c, d; 75 while (~scanf("%d %d", &n, &Mod)) { 76 seg.built(1, 1, n); 77 scanf("%d", &m); 78 while (m--) { 79 scanf("%d", &a); 80 if (1 == a) { 81 scanf("%d %d %d", &b, &c, &d); 82 seg.update(1, 1, n, b, c, 0, d); 83 } else if (2 == a) { 84 scanf("%d %d %d", &b, &c, &d); 85 seg.update(1, 1, n, b, c, d, 1); 86 } else { 87 scanf("%d %d", &b, &c); 88 printf("%lld\n", seg.query(1, 1, n, b, c)); 89 } 90 } 91 } 92 return 0; 93 }