题意: 有一个序列,首先有两种操作:①查找后L个数中最大数;②[(最近一次查询得到的答案 + 常数R) % 常数D] 得到一个新数插入到序列的末尾,如果序列中没有数,那么用 0 代替 最近一次查询得到的答案。
题解:一个数插入到序列中,查询时她会影响到前面比它小的数;也就是说一个新数插入,那么这个数前面的比它小的数将没有贡献。所以想到单调队列作为此题的核心算法。
CODE:
/*
Author: JDD
PROG: bzoj1012 最大数
DATE: 2015.9.22
*/
#include <cstdio>
#define REP(i, s, n) for(int i = s; i <= n; i ++)
#define REP_(i, s, n) for(int i = n; i >= s; i --)
#define MAX_N 200005
using namespace std;
int M, D, N = 0, h = 1, t = 1;
int a[MAX_N], R[MAX_N];
int find(int x)
{
int l = h, r = t, mid;
while(l < r){
mid = (l + r) >> 1;
if(R[mid] >= x) r = mid;
else l = mid + 1;
}
return l;
}
void work()
{
scanf("%d%d", &M, &D);
int ans = 0;
while(M --){
char s[3]; int x;
scanf("%s%d", s + 1, &x);
if(s[1] == 'A'){
a[++ N] = (x + ans) % D;
while(h < t && a[R[t]] < a[N]) t --;
R[++ t] = N;
} else {
ans = a[R[find(N - x + 1)]];
//printf("%d\n", find(N - x + 1));
printf("%d\n", ans);
}
/*REP(i, 1, t) printf("%d ", R[i]);
printf("\n");*/
}
}
int main()
{
work();
return 0;
}