【BZOJ1798】【Ahoi2009】Seq 维护序列(线段树)
链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798
唔这是好久好久以前写不出的题了QAQ,就是一个线段树水题qvq
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 #define MaxN 100010 7 #define MaxM 200010 8 #define LL long long 9 using namespace std; 10 LL p, ans; 11 int n, m, root = 0, S = 0, L, R; 12 int ch[MaxM][2], da[MaxN]; 13 LL sz[MaxM], mu[MaxM], ad[MaxM], sum[MaxM], val[MaxM]; 14 15 #define l ch[x][0] 16 #define r ch[x][1] 17 #define mid (a+b) / 2 18 19 void updata(int x, LL multi, LL add){ 20 if (!x) return; 21 sum[x] = (sum[x] * multi % p + sz[x] * add) % p; 22 ad[x] = (ad[x] * multi + add) % p; 23 mu[x] = (mu[x] * multi) % p; 24 } 25 26 void push_up(int x){ 27 sum[x] = (sum[l] + sum[r]) % p; 28 } 29 30 void push_down(int x){ 31 LL MU = mu[x], AD = ad[x]; 32 if (MU != 1ll || AD != 0ll){ 33 updata(l, MU, AD); updata(r, MU, AD); 34 mu[x] = 1ll; ad[x] = 0ll; 35 } 36 } 37 38 void Build(int &x, int a, int b){ 39 x = ++S; 40 mu[x] = 1ll, ad[x] = 0ll; 41 if (a == b) { sum[x] = (LL)da[a]; sz[x] = 1ll; return; } 42 Build(ch[x][0], a, mid); 43 Build(ch[x][1], mid+1, b); 44 sz[x] = sz[ch[x][0]] + sz[ch[x][1]]; 45 push_up(x); 46 } 47 48 void query(int x, int a, int b){ 49 push_down(x); 50 if (L <= a && R >= b) { 51 ans = (ans + sum[x]) % p; 52 return ; 53 } 54 if (L <= mid) query(l, a, mid); 55 if (R > mid) query(r, mid+1, b); 56 push_up(x); 57 } 58 59 void change(int x, int a, int b, LL c, int q){ 60 push_down(x); 61 if (L <= a && R >= b) { 62 if (q == 1) updata(x, c, 0ll); 63 else updata(x, 1ll, c); 64 return ; 65 } 66 if (L <= mid) change(l, a, mid, c, q); 67 if (R > mid) change(r, mid+1, b, c, q); 68 push_up(x); 69 } 70 71 int main(){ 72 int q, c; 73 scanf("%d%lld", &n, &p); 74 for (int i = 1; i <= n; i++) scanf("%d", &da[i]); 75 memset(mu, 1ll, sizeof(mu)); 76 Build(root, 1, n); 77 scanf("%d", &m); 78 for (int i = 1; i <= m; i++) { 79 scanf("%d%d%d", &q, &L, &R); 80 if (q != 3) { 81 scanf("%d", &c); 82 change(root, 1, n, (LL)c, q); 83 } 84 else ans = 0ll, query(root, 1, n), printf("%lld\n", ans); 85 } 86 return 0; 87 }