1 #include
2 #include
3 #include
4 #include
5 #include
6 using namespace std;
7 const int maxn = 100000+ 10;
8
9 //update_add:把A[L]~A[R]的值全部加v_add
10 //update_set:把A[l]~A[R]的值设为v_set
11 //query:计算子序列的元素和,最小值,最大值
12
13 int sumv[2*maxn],minv[2*maxn],maxv[2*maxn];
14 int addv[2*maxn], setv[2*maxn];
15 int y1, y2, v_add, v_set;
16
17 void maintain(int o, int L, int R) {
18 int lc = 2*o, rc = 2*o + 1;
19 sumv[o] = minv[o] = maxv[o] = 0;
20 if(setv[o] >= 0) {
21 sumv[o] = setv[o] * (R-L+1);
22 minv[o] = maxv[o] = setv[o];
23 }
24 else if(R > L) {
25 sumv[o] = sumv[lc] + sumv[rc];
26 minv[o] = min(minv[lc], minv[rc]);
27 maxv[o] = max(maxv[lc], maxv[rc]);
28 }
29 minv[o] += addv[o]; maxv[o] += addv[o]; sumv[o] += addv[o] * (R-L+1);
30 }
31 void pushdown(int o) {
32 int lc = 2*o, rc = 2*o+1;
33 if(setv[o] >= 0) {
34 setv[lc] = setv[rc] = setv[o];
35 addv[lc] = addv[rc] = 0;
36 setv[o] = -1;
37 }
38 if(addv[o] > 0) {
39 addv[lc] += addv[o];
40 addv[rc] += addv[o];
41 addv[o] = 0;
42 }
43 }
44 void update_add(int o, int L, int R) {
45 int lc = 2*o, rc = o*2+1;
46 if(y1 <= L && y2 >= R) {
47 addv[o] += v_add;
48 }
49 else {
50 pushdown(o);
51 int M = L + (R-L)/2;
52 if(y1 <= M) update_add(lc, L, M); else maintain(lc, L, M);
53 if(y2 > M) update_add(rc, M+1, R);else maintain(rc, M+1, R);
54 }
55 maintain(o, L, R);
56 }
57 void update_set(int o, int L, int R) {
58 int lc = 2*o, rc = o*2+1;
59 if(y1 <= L && y2 >= R) {
60 setv[o] = v_set;
61 addv[o] = 0;
62 }
63 else {
64 pushdown(o);
65 int M = L + (R-L)/2;
66 if(y1 <= M) update_set(lc, L, M); else maintain(lc, L, M);
67 if(y2 > M) update_set(rc, M+1, R); else maintain(rc, M+1, R);
68 }
69 maintain(o, L, R);
70 }
71 int _min, _max, _sum;
72 void query(int o, int L, int R, int add) {
73 if(setv[o] >= 0) {
74 _sum += (add+setv[o]+addv[o]) * (min(R, y2)-max(L, y1)+1);
75 _min = min(_min, setv[o]+addv[o]+add);
76 _max = max(_max, setv[o]+addv[o]+add);
77 }
78 else if(y1 <= L && y2 >= R) {
79 _sum += sumv[o] + add * (R-L+1);
80 _min = min(_min, minv[o]+add);
81 _max = max(_max, maxv[o]+add);
82 }
83 else {
84 int M = L + (R-L)/2;
85 if(y1 <= M) query(o*2, L, M, add+addv[o]);
86 if(y2 > M) query(o*2+1, M+1, R, add + addv[o]);
87 }
88 }
89 void init() {
90 memset(setv, -1, sizeof setv);
91 memset(addv, 0, sizeof addv);
92 memset(sumv, 0, sizeof sumv);
93 memset(minv, 0, sizeof minv);
94 memset(maxv, 0, sizeof maxv);
95 }