上题!
算法:
用线段树维护该数列,计len做长度,计t为上次查询所得答案,
操作就将模板的加上该数改为取最大值即可。
程序:
#include<bits/stdc++.h>
#define rep(i,n,k) for(int i=n;i<=k;i++)
using namespace std;
struct wzy{
int l,r;
long long value;
}tree[800010];
void build(int ll,int rr,int number){
if(ll>rr)return;
tree[number].l=ll;tree[number].r=rr;tree[number].value=-INT_MAX;
if(ll==rr)return;
int mid=(ll+rr)/2;
build(ll,mid,number*2);build(mid+1,rr,number*2+1);
return;
}
void down_stream(int in_place,long long in_value,int number){
if(!tree[number].l)return;
if(tree[number].l==tree[number].r){tree[number].value=max(tree[number].value,in_value);return;}
int tree_mid=(tree[number].l+tree[number].r)/2;
if(in_place<=tree_mid)down_stream(in_place,in_value,number*2);
if(in_place>tree_mid)down_stream(in_place,in_value,number*2+1);
tree[number].value=max(tree[number*2].value,tree[number*2+1].value);
return;
}
long long query(int ql,int qr,int number){
if(!tree[number].l)return -INT_MAX;
if(ql<=tree[number].l&&tree[number].r<=qr){
return tree[number].value;
}else{
long long ans=-INT_MAX;
int tree_mid=(tree[number].l+tree[number].r)/2;
if(ql<=tree_mid)ans=max(ans,query(ql,qr,number*2));
if(qr>tree_mid)ans=max(ans,query(ql,qr,number*2+1));
return ans;
}
}
int main(){
int M;long long D;scanf("%d%lld",&M,&D);
build(1,200000,1);
int len=0;long long t=0;
rep(i,1,M){
char ch;cin>>ch;
long long n;scanf("%lld",&n);
if(ch=='A'){
down_stream(len+1,(n+t)%D,1);len++;
}else{
t=query(len-n+1,len,1);printf("%d\n",t);
}
}
return 0;
}