【BZOJ1798】【Ahoi2009】Seq 维护序列（线段树）

 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;
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){
32     if (MU != 1ll || AD != 0ll){
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 }

posted @ 2016-01-22 20:35  Lukaluka  阅读(377)  评论(1编辑  收藏  举报