Submit: 6471 Solved: 2756
[Submit][Status][Discuss]
Description
现在请求你维护一个数列,要求提供以下两种操作: 1、 查询操作。语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。限制:L不超过当前数列的长度。 2、 插入操作。语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。限制:n是非负整数并且在长整范围内。注意:初始时数列是空的,没有一个数。
Input
第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),D如上文中所述,满足(0
Output
对于每一个查询操作,你应该按照顺序依次输出结果,每个结果占一行。
Sample Input
5 100
A 96
Q 1
A 97
Q 1
Q 2
A 96
Q 1
A 97
Q 1
Q 2
Sample Output
96
93
96
93
96
HINT
Source
线段树求区间最值,如果能动态开点就更好了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cmath> 5 #include<algorithm> 6 #include<cstring> 7 #include<vector> 8 #include<queue> 9 using namespace std; 10 typedef long long LL; 11 const LL maxn=200005; 12 const LL inf=1e15; 13 inline LL read(){ 14 LL x=0,f=1;char ch=getchar(); 15 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 16 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 17 return x*f; 18 } 19 LL N,M,D; 20 LL tot=1; 21 LL a[maxn]; 22 LL NOW; 23 char c[10]; 24 LL P; 25 struct node{ 26 LL num; 27 LL MAX; 28 LL l,r,lc,rc; 29 }seg[maxn*8]; 30 inline void Build(LL root,LL l,LL r){ 31 seg[root].num=tot; 32 seg[root].l=l; seg[root].r=r; 33 if(seg[root].l==seg[root].r){ 34 seg[root].MAX=a[l]; 35 return; 36 } 37 LL mid=(seg[root].l+seg[root].r)>>1; 38 seg[root].lc=++tot; Build(tot,l,mid); 39 seg[root].rc=++tot; Build(tot,mid+1,r); 40 seg[root].MAX=max(seg[seg[root].lc].MAX,seg[seg[root].rc].MAX); 41 } 42 inline LL query(LL root,LL l,LL r){ 43 if(l<=seg[root].l&&seg[root].r<=r){ 44 return seg[root].MAX; 45 } 46 LL mid=(seg[root].l+seg[root].r)>>1; 47 LL ans=-inf; 48 if(l<=mid) ans=max(ans,query(seg[root].lc,l,r)); 49 if(mid+1<=r) ans=max(ans,query(seg[root].rc,l,r)); 50 seg[root].MAX=max(seg[seg[root].lc].MAX,seg[seg[root].rc].MAX); 51 return ans; 52 } 53 inline void change(LL root,LL l,LL r,LL delta){ 54 if(l<=seg[root].l&&seg[root].r<=r){ 55 seg[root].MAX=delta; 56 return ; 57 } 58 LL mid=(seg[root].l+seg[root].r)>>1; 59 if(l<=mid) change(seg[root].lc,l,r,delta); 60 if(mid+1<=r) change(seg[root].rc,l,r,delta); 61 seg[root].MAX=max(seg[seg[root].lc].MAX,seg[seg[root].rc].MAX); 62 } 63 int main(){ 64 scanf("%lld%lld",&M,&D); 65 for(int i=1;i<=M;i++) a[i]=-inf; 66 Build(1,1,M); 67 for(LL i=1;i<=M;i++){ 68 scanf("%s",c); 69 if(c[0]=='A'){ 70 scanf("%lld",&P); 71 P=(P+NOW)%D; 72 N++; 73 change(1,N,N,P); 74 } 75 else{ 76 scanf("%lld",&P); 77 NOW=query(1,N-P+1,N); 78 printf("%lld ",NOW); 79 } 80 } 81 return 0; 82 }