【BZOJ】1012 [JSOI2008] 最大数maxnumber

来源:互联网 发布:知乎日报app 编辑:程序博客网 时间:2024/05/18 00:34

Description

现在请求你维护一个数列,要求提供以下两种操作:

1、 查询操作。语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。限制:L不超过当前数列的长度。

2、 插入操作。语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。

限制:n是非负整数并且在长整范围内。注意:初始时数列是空的,没有一个数。

Input

第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),D如上文中所述,满足D在longint内。接下来M行,查询操作或者插入操作。

Solution

操作全部都是往最后插数,并且只需要维护后缀最大值所以……
(想到什么奇奇怪怪的数据结构的八成是数据结构学傻了=w=)

用一个单调栈维护最大值就好了,弹出条件是栈顶不比当前的元素大。查询操作在栈中二分。

#include<stdio.h>int n,mod,t,e,tot,p[200002],l,r,mid,k;long long a[200002];int main(){    scanf("%d%d",&n,&mod);    a[0]=2333333333333333333LL;    while (n--)    {        char ch=getchar();        while (ch!='A' && ch!='Q') ch=getchar();        scanf("%d",&k);        if (ch=='A')        {            k=((long long)k+t) % mod;            while (a[e]<=k) e--;            a[++e]=k;            p[e]=++tot;        }        else        {            for (l=0,r=e,mid=e>>1;l<r;mid=(l+r)>>1) if (p[mid]<tot-k+1) l=mid+1;            else r=mid;            printf("%d\n",t=(l==0?0:(int)a[l]));        }    }}
0 0
原创粉丝点击