题目描述
现在请求你维护一个数列,要求提供以下两种操作:
1、 查询操作。
语法:Q L
功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。
限制: L 不超过当前数列的长度。 (L > 0)
2、 插入操作。
语法:A n
功能:将 n 加上 t,其中 t 是最近一次查询操作的答案(如果还未执行过查询操作,则 t=0 ),并将所得结果对一个固定的常数 D 取模,将所得答案插入到数列的末尾。
限制: n 是整数(可能为负数)并且在长整范围内。
注意:初始时数列是空的,没有一个数。
输入输出格式
输入格式:
第一行两个整数, M和 D ,其中 M 表示操作的个数 (M le 200,000), DD 如上文中所述,满足 (0<D<2,000,000,000)
接下来的 M 行,每行一个字符串,描述一个具体的操作。语法如上文所述。
输出格式:
对于每一个查询操作,你应该按照顺序依次输出结果,每个结果占一行。
输入输出样例
#include <bits/stdc++.h> using namespace std; const int MAXN=200010; int h[MAXN]; int lowbit(int x) { return x&(-x); } int n; void updata(int i,int val) { while(i>0) { h[i]=max(val,h[i]); i-=lowbit(i); } } int query(int x,int y) { int ans=0; while(x<=y) { ans=max(h[y],ans); y--; for (;y-lowbit(y)>=x;y-=lowbit(y)) { ans=max(h[y],ans); } } return ans; } int main() { int m,d; scanf("%d%d",&m,&d); char s[2]; n=1; int t=0; for (int i = 0; i <m ; ++i) { scanf("%s",s); if(s[0]=='Q') { int L; scanf("%d",&L); int ans=query(n-L,n); t=ans; printf("%d ",ans); } else if(s[0]=='A') { int x; scanf("%d",&x); x=(x+t)%d; updata(n,x); n++; } } return 0; }