[BZOJ1012]&&[JSOI2008] 最大数 maxnumber

描述 Description

现在请求你维护一个数列,要求提供以下两种操作: 1、 查询操作。语法:Q L 功能:查询当前数列中末尾 L 个数中的最大的数,并输出这个数的值。限制:L 不超过当前数列的长度。 2、 插入操作。语法:A n 功能:将 n 加上 t,其中 t 是最近一次查询操作的答案(如果还未执行过查询操作,则 t=0),并将所得结果对一个固定的常数 D 取模,将所得答案插入到数列的末尾。限制:n 是非负整数并且在长整范围内。注意:初始时数列是空的,没有一个数。

输入格式 InputFormat

第一行两个整数,M 和 D,其中 M 表示操作的个数 (M <= 200,000),D 如上文中所述,满足 (0

输出格式 OutputFormat

对于每一个查询操作,你应该按照顺序依次输出结果,每个结果占一行。

样例输入 SampleInput

5 100
A 96
Q 1
A 97
Q 1
Q 2

样例输出 SampleOutput

96
93
96

数据范围和注释 Hint

对于 100% 的数据,满足 0<=xi,x0<=10000,0 #include #include #include #include using namespace std; int i,j,t,n,m,l,r,k,z,y,x; inline void read(int &x) { x=0;char ch=getchar(); while (ch<‘0’ || ch>‘9’) ch=getchar(); while (ch>=‘0’ && ch<=‘9’) x=x*10+ch-‘0’,ch=getchar(); } int D,q,M; int a[200005]; int s[200005]; char ch; void ins(int x) { int i,j,t; a[++n]=(x+q)%D; while (m!=0 && a[s[m]]<a[n]) m–; s[++m]=n; } void print(int x) { int i,j,t; t=lower_bound(s+1,s+m+1,n-x+1)-s; q=a[s[t]]; printf(“%d”,q); } int main() { q=m=0; read(M);read(D); n=0; for (i=1;i<=M;i++) { scanf(“%c”,&ch); read(x); if (ch==‘A’) ins(x); if (ch==‘Q’) print(x); } return 0; } ```