P1988 最大数
最大数
08年江苏的一道省选题。
题目描述:
用两种操作维护一个数列:
1、 查询:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。
2、 插入:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。
这道题的解决方法有不少,例如单调栈,单调队列,线段树之类的。
由于把这道题当作单调栈的练习来做的,所以就只用了单调栈。别的方法可以参考一下黄学长的博客。
思路:
不断的维护一个单调递减的栈,每次输出后面要求输出的第n位就好了。
代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 using namespace std; 5 int n,m,b,sum[200010],dis[2000010],top,x,num; 6 char a[1]; 7 int main(){ 8 scanf("%d%d",&n,&m); 9 for(int i=1;i<=n;++i){ 10 scanf("%s%d",a,&b); 11 if(a[0]=='A'){ 12 b=(b+x)%m; 13 sum[++num]=b; 14 while(top&&sum[dis[top]]<=b) 15 top--; 16 dis[++top]=num; 17 } 18 else{ 19 int y=lower_bound(dis+1,dis+top+1,num-b+1)-dis; 20 x=sum[dis[y]]; 21 printf("%d\n",x); 22 } 23 } 24 return 0; 25 }