题意;初始序列为空,Q次操作.Q,D<=2e5
op1:询问末尾Li个数的最大值 op2:向末尾插入x+上一次的查询的答案%D.(在线)
若一个数右边有比它大的数,则查询末尾最值时可以将该数淘汰.
op1:询问末尾Li个数的最大值 op2:向末尾插入x+上一次的查询的答案%D.(在线)
若一个数右边有比它大的数,则查询末尾最值时可以将该数淘汰.
单调栈维护第i大的位置.每次二分找到第一个大于n-L+1的位置即可.次二分找到第一个大于n-L+1的位置即可.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e5+20;
const ll inf=1e18;
ll a[N],top,num[N];
int main()
{
int Q,D;
char ch[10];
while(cin>>Q>>D)
{
ll n=0,x,ans,t=0,top=0;
while(Q--)
{
scanf("%s%lld",ch,&x);
if(ch[0]=='A')
{
x=(x+t)%D;
num[++n]=x;
while(top&&x>=num[a[top]])
top--;
a[++top]=n;
}
else
{
int y=lower_bound(a+1,a+1+top,n-x+1)-a;
t=num[a[y]];
printf("%lld\n",t);
}
}
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e5+20;
const ll inf=1e18;
struct node{ll l,r,mx;}t[N*4];
void push_up(int o){t[o].mx=max(t[o<<1].mx,t[o<<1|1].mx);}
void build(int o,int l,int r)
{
t[o].l=l,t[o].r=r;
if(l==r){t[o].mx=-inf;return;}
int m=l+r>>1;
build(o<<1,l,m),build(o<<1|1,m+1,r);
push_up(o);
}
void update(int o,int pos,ll x)
{
int l=t[o].l,r=t[o].r,m=l+r>>1;
if(l==r){t[o].mx=x;return;}
if(pos<=m) update(o<<1,pos,x);
else update(o<<1|1,pos,x);
push_up(o);
}
ll query(int o,int ql,int qr)
{
int l=t[o].l,r=t[o].r,m=l+r>>1;
if(l>=ql&&r<=qr) return t[o].mx;
ll res=0;
if(ql<=m) res=max(res,query(o<<1,ql,qr));
if(qr>m) res=max(res,query(o<<1|1,ql,qr));
return res;
}
int main()
{
int Q,D;
char ch[10];
while(cin>>Q>>D)
{
ll n=0,x,ans,t=0;
build(1,1,100010);
while(Q--)
{
scanf("%s%lld",ch,&x);
if(ch[0]=='A')
n++,update(1,n,(x+t)%D);
else
{
t=query(1,n-x+1,n);;
printf("%lld\n",t);
}
}
}
return 0;
}