题意:初始为空,两种操作::(1) Q L :查询当前数列中末尾L个数中的最大的数,并输出这个数的值。保证L不超过当前数列的长度。(2)A n :将n加上最近一次查询操作的答案(如果还未执行过查询操作,则t=0),对常数D取模,将所得答案插入到数列的末尾。
一眼过去,直觉告诉我是线段树...
type
rec=record
l,r,max:longint;
end;
var
n,m,tt,mo,x :longint;
ch :char;
i :longint;
t :array[0..800010] of rec;
function max(a,b:longint):longint;
begin
if a<b then exit(b) else exit(a);
end;
procedure build(x,l,r:longint);
var
mid:longint;
begin
t[x].l:=l; t[x].r:=r;
if l=r then exit;
mid:=(l+r)>>1;
build(2*x,l,mid);
build(2*x+1,mid+1,r);
end;
procedure insert(x,y,z:longint);
var
mid:longint;
begin
if t[x].l=t[x].r then
begin
t[x].max:=z;exit;
end;
mid:=(t[x].l+t[x].r)>>1;
if y<=mid then insert(2*x,y,z)
else insert(2*x+1,y,z);
t[x].max:=max(t[2*x].max,t[2*x+1].max);
end;
function get_max(x,l,r:longint):longint;
var
mid:longint;
begin
if (t[x].l=l) and (t[x].r=r) then exit(t[x].max);
mid:=(t[x].l+t[x].r)>>1;
if r<=mid then exit(get_max(2*x,l,r)) else
if l>mid then exit(get_max(2*x+1,l,r)) else
exit(max(get_max(2*x,l,mid),get_max(2*x+1,mid+1,r)));
end;
begin
readln(m,mo); tt:=0; n:=0;
build(1,1,m);
for i:=1 to m do
begin
read(ch);readln(x);
if ch='A' then
begin
inc(n);
x:=(x+tt) mod mo;
insert(1,n,x);
end else
begin
tt:=get_max(1,n-x+1,n);
writeln(tt);
end;
end;
end.
——by Eirlys