P1198 [JSOI2008]最大数
题目描述
现在请求你维护一个数列,要求提供以下两种操作:
1、 查询操作。
语法:Q L
功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。
限制:L不超过当前数列的长度。
2、 插入操作。
语法:A n
功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。
限制:n是整数(可能为负数)并且在长整范围内。
注意:初始时数列是空的,没有一个数。
输入输出格式
输入格式:第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),D如上文中所述,满足(0<D<2,000,000,000)
接下来的M行,每行一个字符串,描述一个具体的操作。语法如上文所述。
输出格式:对于每一个查询操作,你应该按照顺序依次输出结果,每个结果占一行。
输入输出样例
输入样例#1:
5 100 A 96 Q 1 A 97 Q 1 Q 2
输出样例#1:
96 93 96
说明
[JSOI2008]
思路
线段树小试牛刀!qwq
先建一颗空的线段树,然后每次把值插入,用num统计个数
然后每次查询num-n+1到num这个区间的最大值输出就是啦
代码
1 program maxnumber; 2 const 3 inf='maxnumber.in'; 4 outf='maxnumber.out'; 5 type 6 tree=^node; 7 node=record 8 lc,rc:tree; 9 l,r,val:longint; 10 end; 11 12 var 13 i,m,n,d,ctot,num,l:longint; 14 ch:char; 15 t:tree; 16 s,e,a:array[1..200000] of longint; 17 18 function max(aa,bb:longint):longint; 19 begin 20 if aa>bb then exit(aa) 21 else exit(bb); 22 end; 23 24 function min(aa,bb:longint):longint; 25 begin 26 if aa>bb then exit(bb) 27 else exit(aa); 28 end; 29 30 procedure add(apple:longint); 31 begin 32 inc(num); 33 a[num]:=apple mod d; 34 end; 35 36 procedure add(var t:tree; seat:longint; data:longint); 37 begin 38 if t^.l=t^.r then begin 39 t^.val:=max(t^.val,data); 40 exit; 41 end; 42 if seat<=t^.lc^.r then add(t^.lc,seat,data) 43 else add(t^.rc,seat,data); 44 t^.val:=max(t^.val,data); 45 end; 46 47 procedure build(var t:tree; l,r:longint); 48 var 49 mid:longint; 50 begin 51 new(t); 52 t^.l:=l; t^.r:=r; 53 if l=r then begin 54 t^.val:=a[l]; 55 exit; 56 end; 57 mid:=(l+r) div 2; 58 build(t^.lc,l,mid); 59 build(t^.rc,mid+1,r); 60 t^.val:=max(t^.lc^.val,t^.rc^.val); 61 end; 62 63 function query(var t:tree; l,r:longint):longint; 64 var 65 mm:longint; 66 begin 67 if (t^.l=t^.r) or ((t^.l>=l) and (t^.r<=r)) then exit(t^.val); 68 mm:=-maxlongint; 69 if l<=t^.lc^.r then mm:=query(t^.lc,l,min(t^.lc^.r,r)); 70 if r>=t^.rc^.l then mm:=max(mm,query(t^.rc,max(t^.rc^.l,l),r)); 71 exit(mm); 72 end; 73 74 begin 75 // assign(input,inf); assign(output,outf); 76 reset(input); rewrite(output); 77 78 readln(m,d); 79 build(t,1,m); 80 l:=0; 81 for i:= 1 to m do 82 begin 83 readln(ch,n); 84 if ch='A' then begin num:=num+1; add(t,num,(n+l) mod d); end 85 else begin 86 l:=query(t,num-n+1,num); 87 writeln(l); 88 end; 89 end; 90 91 close(input); 92 close(output); 93 end.