这题其实用线段树就蛮好做的,其实都不用建树,不过要注意可能有输入为0的序列,这时候就会变得特别坑,然后我提交了好多次才解决的。
#include<cstdio>
const int MAXN = 200000 + 6;
int a[MAXN];
class SegmentTree{
public:int l,r;
public:int max;
};
SegmentTree t[MAXN * 4];
inline int LEFT(int x){return x << 1;}
inline int RIGHT(int x){return x << 1 | 1;}
inline int MID(int l,int r){return (l + r) >> 1;}
inline int max(int a,int b){return a > b ? a : b;}
void build(int p,int l,int r){
t[p].l = l;t[p].r = r;
if(l == r){
t[p].max = a[l];
return;
}
build(LEFT(p),l,MID(l,r));
build(RIGHT(p),MID(l,r) + 1,r);
t[p].max = max(t[LEFT(p)].max,t[RIGHT(p)].max);
}
void change(int p,int x,int v){
if(t[p].l == t[p].r){
t[p].max = v;
return;
}
if(x <= MID(t[p].l,t[p].r)){
change(LEFT(p),x,v);
}else{
change(RIGHT(p),x,v);
}
t[p].max = max(t[LEFT(p)].max,t[RIGHT(p)].max);
}
int ask(int p,int l,int r){
if(l <= t[p].l && r >= t[p].r){
return t[p].max;
}
int ans = -0x7fffffff;
if(l <= MID(t[p].l,t[p].r)){
ans = max(ans,ask(LEFT(p),l,r));
}
if(r > MID(t[p].l,t[p].r)){
ans = max(ans,ask(RIGHT(p),l,r));
}
return ans;
}
int main(){
int m,d;
scanf("%d %d\n",&m,&d);
int ans = 0,j = 0;
for(int i = 1;i <= m;i++){
a[i] = -0x7fffffff;
}
build(1,1,m);
while(m--){
char op;
int key;
scanf("%c %d\n",&op,&key);
if(op == 'A'){
j++;
change(1,j,(key + ans) % d);
}else{
if(key == 0){
ans = 0;
}else{
ans = ask(1, j - key + 1,j) % d;
}
printf("%d\n",ans);
}
}
return 0;
}