线段树
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
struct aa
{
int l,r,mx;
}a[200005*4];
int n,tot,m,mod;
void build(int i,int l,int r)
{
a[i].l=l;a[i].r=r;
if (l==r) return ;
int mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
}
void add(int i,int x,int val)
{
if (a[i].l==a[i].r) {a[i].mx=val;return ;}
int mid=(a[i].l+a[i].r)>>1;
if (mid>=x) add(i<<1,x,val);
else add(i<<1|1,x,val);
a[i].mx=max(a[i<<1].mx,a[i<<1|1].mx);
}
int query(int i,int l,int r)
{
if (a[i].l==l&&a[i].r==r) return a[i].mx;
int mid=(a[i].l+a[i].r)>>1;
if (mid>=r) return query(i<<1,l,r);
else if (mid<l) return query(i<<1|1,l,r);
else return max(query(i<<1,l,mid),query(i<<1|1,mid+1,r));
}
int main()
{
scanf("%d%d",&m,&mod);
build(1,1,m);
char ch[2];
int x,last=0;
while (m--)
{
scanf("%s%d",ch,&x);
if (ch[0]=='A')
add(1,++tot,(x+last)%mod);
else printf("%d\n",last=query(1,tot-x+1,tot));
}
return 0;
}
单调队列,取后面那个区间最大值,在单调队列中用二分查找处理
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,last,mod;
int q[200005],id[200005],head,tail;
void add(int x)
{
while (q[tail]<=x && tail) tail--;
q[++tail]=x;id[tail]=++n;
}
int query(int x)
{
int l=n-x+1;
int k=lower_bound(id+head,id+tail+1,l)-id;
return q[k];
}
int main()
{
scanf("%d%d",&m,&mod);
char ch[2];
int x;
head=1;tail=0;
while (m--)
{
scanf("%s%d",ch,&x);
if (ch[0]=='A')
add((x+last)%mod);
else printf("%d\n",last=query(x));
}
return 0;
}