洛谷P1198 [JSOI2008]最大数

传送门

题意

自己看原题啊

题解

直接建一颗有 $M$ 个节点的线段树,然后单点修改、区间查询最大值即可。

时间复杂度: $\mathcal O(m \mathrm{lg} m)$ 。

上代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 struct SgTree{
 5     #define segc int M = L + R - 1 >> 1, lc = id << 1, rc = lc | 1
 6     int sz;
 7     struct node {int v, f; bool zero;} *x;
 8     SgTree (): sz(0) {x = NULL;}
 9     ~SgTree () {if(x) delete [] (x);}
10     void resize(int size) {sz = size; int sz0 = sz << 3; if(x) delete [] (x);
11         x = new node[sz0]; memset(x, 0, sz0 * sizeof(node));}
12 
13     void add(int h, int v) {add(1, 1, sz, h, v);}
14     int range(int l, int r) {return query(1, 1, sz, l, r);}
15 
16     void add(int id, int L, int R, int h, int v){
17         if(L == R) return void(x[id].v += v);
18         segc; h <= M ? add(lc, L, M, h, v) : add(rc, M + 1, R, h, v);
19         x[id].v = max(x[lc].v, x[rc].v);
20     }
21 
22     int query(int id, int L, int R, int ql, int qr){
23         if(ql <= L && R <= qr) return x[id].v;
24         segc, s = 0;
25         if(ql <= M) s = max(s,query(lc, L, M, ql, min(qr, M)));
26         if(qr > M) s = max(s,query(rc, M + 1, R, max(ql, M + 1), qr));
27         return s;
28     }
29 } ST;
30 
31 int main() {
32     ios :: sync_with_stdio(false);
33     int m, d, lastans = 0;
34     cin >> m >> d;
35     ST.resize(m); int n = 0;
36     while (m--) {
37         char op[5]; int v;
38         cin >> op >> v;
39         if (op[0] == 'Q') {
40             cout << (lastans = ST.range(max(1, n-v+1), n)) << endl;
41         } else {
42             ++n; ST.add(n, (v + lastans) % d);
43         }
44     }
45     return 0;
46 }

猜你喜欢

转载自www.cnblogs.com/mchmch/p/luogu-p1198.html