P1198 [JSOI2008] 最大数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
//线段树
#include<bits/stdc++.h>
using namespace std;
const int maxn=200010;
struct node
{
int mmax,mmin;
int l,r;
}tree[maxn*4];
void bulid(int x,int l,int r)
{
tree[x].l=l,tree[x].r=r;
if(l==r)
{
tree[x].mmax = -1e9;
return;
}
int mid=(l+r)>>1;
bulid(x<<1,l,mid);
bulid(x<<1|1,mid+1,r);
tree[x].mmax = max(tree[x<<1].mmax,tree[x<<1|1].mmax);
}
void change(int x,int l,int r,int k)
{
if(l<=tree[x].l&&tree[x].r<=r)
{
tree[x].mmax=k;
return;
}
int mid=tree[x].l+tree[x].r>>1;
if(l<=mid)
{
change(x<<1,l,r,k);
}
if(r>mid)
{
change(x<<1|1,l,r,k);
}
tree[x].mmax = max(tree[x<<1].mmax,tree[x<<1|1].mmax);
}
int querymax(int x,int l,int r)
{
if(l<=tree[x].l&&tree[x].r<=r)
{
return tree[x].mmax;
}
int mid=tree[x].l+tree[x].r>>1;
int ans1=-1e9,ans2=-1e9;
if(l<=mid)
{
ans1=querymax(x<<1,l,r);
}
if(r>mid)
{
ans2=querymax(x<<1|1,l,r);
}
return max(ans1,ans2);
}
int main()
{
int n,d;
scanf("%d %d",&n,&d);
bulid(1,1,n);
char c;
int q,t=0,r=1;
getchar();
for(int i=0;i<n;i++)
{
cin>>c>>q;
if(c=='A')
{
q=(q+t)%d;
change(1,r,r,q);
r++;
}else
{
t=querymax(1,r-q,r-1);
cout<<t<<endl;
}
}
return 0;
}
//RMQ
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int s[maxn][32];
int lg[maxn+1];
void change(int x,int t)
{
s[t][0]=x;
for(int i=1;(1<<i)<=t;i++)
{
s[t][i]=max(s[t][i-1],s[t-(1<<(i-1))][i-1]);
}
}
void getlog()
{
lg[1]=0;
for(int i=2;i<=maxn;++i)
{
lg[i]=lg[i/2]+1;
}
}
int query(int x,int t)
{
int L=lg[x];
int l=t-x+1;
return max(s[t][L],s[l+(1<<L)-1][L]);
}
int main()
{
ios::sync_with_stdio(false);
long long n,d;
cin>>n>>d;
int temp=0;
int t=0;
getlog();
while(n--)
{
char x;
int a;
cin>>x>>a;
if(x=='A')
{
a=(a+temp)%d;
t++;
change(a,t);
}else
{
temp=query(a,t);
cout<<temp<<endl;
}
}
return 0;
}