Bob需要一个程序来监视CPU使用率。这是一个很繁琐的过程,为了让问题更加简单,Bob会慢慢列出今天会在用计算机时做什么事。
Bob会干很多事,除了跑暴力程序看视频之外,还会做出去玩玩和用鼠标乱点之类的事,甚至会一脚踢掉电源……这些事有的会让做这件事的这段时间内CPU使用率增加或减少一个值;有的事还会直接让CPU使用率变为一个值。
当然Bob会询问:在之前给出的事件影响下,CPU在某段时间内,使用率最高是多少。有时候Bob还会好奇地询问,在某段时间内CPU曾经的最高使用率是多少。
为了使计算精确,使用率不用百分比而用一个整数表示。
不保证Bob的事件列表出了莫名的问题,使得使用率为负………………
第一行一个正整数T,表示Bob需要监视CPU的总时间。
然后第二行给出T个数表示在你的监视程序执行之前,Bob干的事让CPU在这段时间内每个时刻的使用率达已经达到了多少。
第三行给出一个数E,表示Bob需要做的事和询问的总数。
接下来E行每行表示给出一个询问或者列出一条事件:
Q X Y:询问从X到Y这段时间内CPU最高使用率
A X Y:询问从X到Y这段时间内之前列出的事件使CPU达到过的最高使用率
P X Y Z:列出一个事件这个事件使得从X到Y这段时间内CPU使用率增加Z
C X Y Z:列出一个事件这个事件使得从X到Y这段时间内CPU使用率变为Z
时间的单位为秒,使用率没有单位。
X和Y均为正整数(X<=Y),Z为一个整数。
从X到Y这段时间包含第X秒和第Y秒。
保证必要运算在有符号32位整数以内。
1 #include<bits/stdc++.h>
2 const int INF = 2147483647;
3 const int maxn = 100035;
4
5 struct node
6 {
7 int hisMx,mx;
8 int cg,add,cgMx,addMx;
9 bool ce;
10 }f[maxn<<2];
11 int n,m;
12
13 int read()
14 {
15 int num = 0;
16 char ch = getchar();
17 bool fl = 0;
18 for (; !isdigit(ch); ch = getchar())
19 if (ch==‘-‘) fl = 1;
20 for (; isdigit(ch); ch = getchar())
21 num = (num<<1)+(num<<3)+ch-48;
22 if (fl) num = -num;
23 return num;
24 }
25 void pushup(int rt)
26 {
27 f[rt].mx = std::max(f[rt<<1].mx, f[rt<<1|1].mx);
28 // f[rt].hisMx = std::max(f[rt].mx, f[rt].hisMx);
29 f[rt].hisMx = std::max(f[rt<<1].hisMx, f[rt<<1|1].hisMx);
30 }
31 void pushdown(int rt)
32 {
33 // printf("pushdownINFO:\n");
34 for (int i=0; i<=1; i++)
35 {
36 int x = rt<<1|i;
37 f[x].hisMx = std::max(f[x].hisMx, std::max(f[rt].cgMx, f[x].mx+f[rt].addMx));
38 if (f[x].cg!=-INF) f[x].cgMx = std::max(f[x].cgMx, f[x].cg+f[rt].addMx);
39 else f[x].addMx = std::max(f[x].addMx, f[x].add+f[rt].addMx);
40 // if (f[rt].cg){
41 // f[x].add = 0;
42 // f[x].ce = 1, f[x].mx = f[x].cg = f[rt].cg;
43 // f[x].cgMx = std::max(f[x].cg, f[x].cgMx);
44 // }
45 // if (f[rt].add){
46 // f[x].add += f[rt].add;
47 // }
48 // f[x].hisMx = std::max(f[x].hisMx, std::max(f[x].cgMx, f[x].mx+f[x].addMx));
49 if (f[rt].add){
50 if (f[x].cg!=-INF) f[x].cg += f[rt].add;
51 else f[x].add += f[rt].add;
52 f[x].mx += f[rt].add;
53 }
54 // if (f[rt].ce){
55 if (f[rt].cg!=-INF){
56 f[x].mx = f[x].cg = f[rt].cg;
57 f[x].add = 0;
58 }
59 f[x].addMx = std::max(f[x].addMx, f[x].add);
60 f[x].cgMx = std::max(f[x].cgMx, std::max(f[x].cg, f[rt].cgMx));
61 // printf("%d: addMx:%d cgMx:%d hisMx:%d\n",i,f[x].addMx,f[x].cgMx,f[x].hisMx);
62 }
63 // puts("");
64 f[rt].add = f[rt].addMx = 0;
65 f[rt].ce = 0, f[rt].cg = f[rt].cgMx = -INF;
66 }
67 void build(int rt, int l, int r)
68 {
69 f[rt].cg = f[rt].cgMx = -INF;
70 if (l==r){
71 f[rt].hisMx = f[rt].mx = read();
72 // f[rt].cg = f[rt].cgMx = -INF;
73 return;
74 }
75 int mid = (l+r)>>1;
76 build(rt<<1, l, mid), build(rt<<1|1, mid+1, r);
77 pushup(rt);
78 return;
79 }
80 int queryMx(int rt, int L, int R, int l, int r)
81 {
82 if (l!=r) pushdown(rt);
83 if (L <= l&&r <= R) return f[rt].mx;
84 int mid = (l+r)>>1, ret = -INF;
85 if (L <= mid) ret = std::max(ret, queryMx(rt<<1, L, R, l, mid));
86 if (R > mid) ret = std::max(ret, queryMx(rt<<1|1, L, R, mid+1, r));
87 return ret;
88 }
89 int queryHis(int rt, int L, int R, int l, int r)
90 {
91 if (l!=r) pushdown(rt);
92 if (L <= l&&r <= R) return f[rt].hisMx;
93 int mid = (l+r)>>1, ret = -INF;
94 if (L <= mid) ret = std::max(ret, queryHis(rt<<1, L, R, l, mid));
95 if (R > mid) ret = std::max(ret, queryHis(rt<<1|1, L, R, mid+1, r));
96 return ret;
97 }
98 void updateAdd(int rt, int L, int R, int l, int r, int c)
99 {
100 if (l!=r) pushdown(rt);
101 if (L <= l&&r <= R){
102 f[rt].add += c, f[rt].mx += c;
103 // f[rt].addMx = std::max(f[rt].addMx, f[rt].add);
104 f[rt].addMx += c;
105 f[rt].hisMx = std::max(f[rt].mx, f[rt].hisMx);
106 return;
107 }
108 int mid = (l+r)>>1;
109 if (L <= mid) updateAdd(rt<<1, L, R, l, mid, c);
110 if (R > mid) updateAdd(rt<<1|1, L, R, mid+1, r, c);
111 pushup(rt);
112 return;
113 }
114 void updateCover(int rt, int L, int R, int l, int r, int c)
115 {
116 if (l!=r) pushdown(rt);
117 if (L <= l&&r <= R){
118 // f[rt].add = 0;
119 f[rt].ce = 1;
120 f[rt].cgMx = f[rt].mx = f[rt].cg = c;
121 f[rt].hisMx = std::max(f[rt].mx, f[rt].hisMx);
122 return;
123 }
124 int mid = (l+r)>>1;
125 if (L <= mid) updateCover(rt<<1, L, R, l, mid, c);
126 if (R > mid) updateCover(rt<<1|1, L, R, mid+1, r, c);
127 pushup(rt);
128 return;
129 }
130 int main()
131 {
132 n = read();
133 build(1, 1, n);
134 m = read();
135 while (m--)
136 {
137 char ch[5];
138 scanf("%s",ch);
139 int x = read(), y = read(), z;
140 if (ch[0]==‘Q‘)
141 printf("%d\n",queryMx(1, x, y, 1, n));
142 else if (ch[0]==‘A‘)
143 printf("%d\n",queryHis(1, x, y, 1, n));
144 else{
145 z = read();
146 if (ch[0]==‘P‘)
147 updateAdd(1, x, y, 1, n, z);
148 else updateCover(1, x, y, 1, n, z);
149 }
150 }
151 return 0;
152 }