1 Description 2 现在请求你维护一个数列,要求提供以下两种操作: 1、 查询操作。语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。限制:L不超过当前数列的长度。 2、 插入操作。语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。限制:n是非负整数并且在长整范围内。注意:初始时数列是空的,没有一个数。 3 4 Input 5 第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),D如上文中所述,满足(0 6 7 Output 8 对于每一个查询操作,你应该按照顺序依次输出结果,每个结果占一行。 9 10 Sample Input 11 5 100 12 A 96 13 Q 1 14 A 97 15 Q 1 16 Q 2 17 Sample Output 18 96 19 93 20 96
单调栈解法:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstdio> 5 using namespace std; 6 int n,d,t; 7 int top,len,a[200001],num[200001]; 8 int main() 9 { 10 int x;char ch[1]; 11 scanf("%d%d",&n,&d); 12 while(n--) 13 { 14 scanf("%s%d",ch,&x); 15 if(ch[0]=='A') 16 { 17 x=(x+t)%d; 18 num[++len]=x;//存储原始数据 19 while(top&&num[a[top]]<=x)top--;// a[]数组维护单调减队列(a[]储存单调数列在原始数据的位置) 20 a[++top]=len; 21 } 22 else{ 23 int y=lower_bound(a+1,a+top+1,len-x+1)-a; 24 t=num[a[y]]; 25 printf("%d\n",t); 26 } 27 } 28 return 0; 29 }
解法二: 线段树。维护区间最大值;
抓住青春的尾巴。。。