BZOJ 1012: [JSOI2008]最大数maxnumber
Description
现在请求你维护一个数列,要求提供以下两种操作:1、 查询操作。语法:Q L 功能:查询当前数列中末尾L
个数中的最大的数,并输出这个数的值。限制:L不超过当前数列的长度。2、 插入操作。语法:A n 功能:将n加
上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取
模,将所得答案插入到数列的末尾。限制:n是非负整数并且在长整范围内。注意:初始时数列是空的,没有一个
数。
Input
第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),D如上文中所述,满足D在longint内。接下来
M行,查询操作或者插入操作。
Output
对于每一个询问操作,输出一行。该行只有一个数,即序列中最后L个数的最大数。
Sample Input
5 100
A 96
Q 1
A 97
Q 1
Q 2
A 96
Q 1
A 97
Q 1
Q 2
Sample Output
96
93
96
93
96
1 /**************************************************************
2 Problem: 1012
3 User: Hammer_cwz_77
4 Language: C++
5 Result: Accepted
6 Time:836 ms
7 Memory:4412 kb
8 ****************************************************************/
9
10 #include<iostream>
11 #include<cstdio>
12 #define LL long long
13 using namespace std;
14 const int MAXN = 200000+9;
15 LL mx[MAXN],arr[MAXN],D,t,tmp;
16 int tot,m;
17
18 inline int lowbit(int x){return x&(-x);}
19
20 inline void insert(LL x){
21 int w = ++tot; x = (x+t)%D;
22 mx[w] = x; arr[w] = x;
23 for (int i=lowbit(w)>>1;i;i>>=1) mx[w] = max(mx[w], mx[w-i]);
24 }
25
26 inline LL query(int len){
27 int l=tot-len+1, r=tot;
28 LL ans = 0;
29 while (l<=r){
30 if (r-lowbit(r)+1>=l) ans = max(ans, mx[r]),r-=lowbit(r);
31 else ans = max(ans, arr[r]), r--;
32 }
33 t = ans;
34 return ans;
35 }
37
38 int main(){
39 scanf("%d%lld",&m,&D);
40
41 char type[2];
42 for (int i=1;i<=m;i++){
43 scanf("%s%lld",type,&tmp);
44 if (type[0]=='A') insert(tmp);
45 else printf("%lld\n",query(tmp));
46 }
47
48 return 0;
49 }