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

Sample Output

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
",query(tmp));
46     }
47      
48     return 0;
49 }
原文地址:https://www.cnblogs.com/Hammer-cwz-77/p/8511263.html