思路
代码
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int N=200010;
struct point{
int l,r;
int v;
}tr[N*4];
int m,p;
int query(int u,int l,int r){
int v=0;
if(tr[u].l>=l&&tr[u].r<=r)return tr[u].v;//如果当前的树已经被包含再查询区间内了,直接放回v
int mid=tr[u].l+tr[u].r>>1;
if(l<=mid)v=max(v,query(u<<1,l,r));//否则分别考虑再左节点和右节点是否有查询区间
if(r>mid)v=max(v,query(u<<1|1,l,r));
return v;
}
void build(int u,int l,int r){//建树
tr[u]={l,r};
if(l==r)return;
int mid=l+r >> 1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
}
void modify(int u,int x,int v){
if (tr[u].l == x && tr[u].r == x) tr[u].v = v;//如果已经找到了要添加的位置,就直接赋值
else
{
int mid = tr[u].l + tr[u].r >> 1;
if (x <= mid) modify(u << 1, x, v);
else modify(u << 1 | 1, x, v);
tr[u].v = max(tr[u << 1].v, tr[u << 1 | 1].v);//更新父节点
}
}
int main(){
cin >> m >> p;
int n=0;//n表示当前树的长度
int last=0;//last记录一下上一次查询的结果
build(1,1,m);
while(m--){
char c;
int x;
cin >> c >> x;
if(c=='Q'){
last=query(1,n-x+1,n);
cout << last << "\n";
}else{
modify(1,n+1,(last + x) % p);
n++;
}
}
}