洛谷1198 最大数

写了那么多XX树和单调队列后,不如试试爽翻天的倍(R)增(M)吧(Q)。
对于每一个点,维护从它为起点向左2^j长度的最大值。
查询的时候从大往小枚举2^j更新最大值就行。

(等等好像代码注释里面写过这些了)

(不保证代码的正确性。。。反正洛谷的数据水过了。。。)

 

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <cstring>
 6 #include <vector>
 7 
 8 using namespace std;
 9 
10 typedef long long ll;
11 
12 char s[10];
13 ll m, d, a[300000], f[300000][30], x, p, t;
14 
15 /*
16     f[i][j] : 从i开始,往左2^j长度的最大值。
17     f[i][0] = a[i]
18     f[i][j] = max(f[i][j - 1], f[i - (1 << (j - 1))][j - 1])
19 
20     1 2 3 4 5 6 7 8
21 */
22 
23 ll ask(int L, int p){
24     ll ret = -0x3f3f3f3f;
25     while(L){
26         for(int i = 25 ; i >= 0 ; i --){
27             if((1 << i) <= L && (p - (1 << i) + 1) >= 1){
28                 ret = max(ret, f[p][i]);
29                 p -= 1 << i;
30                 L -= 1 << i;
31                 break;
32             }
33         }
34     }
35     return ret;
36 }
37 
38 int main(){
39     scanf("%lld%lld", &m, &d);
40     while(m --){
41         scanf("%s%lld", s, &x);
42         if(*s == 'Q'){
43             printf("%lld\n", t = ask(x, p));
44         }else{
45             a[++ p] = (x + t) % d;
46             f[p][0] = a[p];
47             for(int i = 1 ; i <= 25 ; i ++){
48                 f[p][i] = f[p][i - 1];
49                 if(p - (1 << (i - 1)) >= 1){
50                     f[p][i] = max(f[p][i], f[p - (1 << (i - 1))][i - 1]);
51                 }
52             }
53         }
54     }
55 }
View Code

 

posted @ 2017-08-06 23:04  KingSann  阅读(263)  评论(0编辑  收藏  举报