题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1012
分析:
因为我们查的是末尾某长度下的最大的数。
很显然的是,如果一个数出现在某个数后边,并且这个数大于之前的数,那么之前的数无论如何也不会成为最大的数的。
所以我们可以维护一个单调递减的栈。
每次要加入一个数之前,将栈顶不大于这个数的元素都弹出去。
然后查询的时候,直接二分查找就可以了
当然在实际的实现中,栈中存的是元素的位置
var
a,b:array [0..1000000] of longint;i,j,m,n,ans,t,x,l,r,tot:longint;
s:string;
function get(x:longint):longint;
var
mid,res:longint;
begin
l:=1;
r:=t-1;
res:=1;
while l<=r do
begin
mid:=(l+r) div 2;
if x<=a[mid] then
begin
res:=mid;
r:=mid-1;
end
else l:=mid+1;
end;
exit(a[res]);
end;
begin
readln(n,m);
t:=1;
for i:=1 to n do
begin
readln(s);
x:=0;
for j:=3 to length(s) do
x:=x*10+ord(s[j])-ord('0');
if s[1]='A' then
begin
x:=(x+ans) mod m;
inc(tot);
b[tot]:=x;
while (1<t) and (b[a[t-1]]<=x) do dec(t);
a[t]:=tot;
inc(t);
end;
if s[1]='Q' then
begin
ans:=b[get(tot-x+1)];
writeln(ans);
end;
end;
end.