这道题比裸的线段树难一丁点,注意题目:假装(连题目都要当戏精)
题目大意:
1、给一棵空树:两个操作
2、A操作,在树的末尾(ed)增加一个点(值从上一次查询得来)
3、Q操作,求 (ed-L+1~ed)这个区间的max
4、值要用 龙龙(long long)
解题思路:
1、题目很友(yin)善(hui)地说:操作数量不超过 20W,而且插入操作:每次只插入一个点。
说人话:这棵树最多只管理20W个点,每次新增操作都是增一个点都在队尾!!
2、戏演完了:开一棵20W个点的空树,改点求段,毕。
3、别被 龙龙 坑了哦(反正我没有)
上代码(感觉没有写注解的必要):
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
const int mx=200005;
int lt=0;
struct nodt{int l,r,ls,rs;ll c;}t[mx*2];
void bt(int l,int r)
{
lt++; int x=lt; t[x].l=l;t[x].r=r;t[x].c=0;
int m=(l+r)/2;
if(l<r)
{
t[x].ls=lt+1; bt(l,m);
t[x].rs=lt+1; bt(m+1,r);
}
}
ll fmax(int x,int l,int r)
{
if(t[x].l==l && t[x].r==r) return t[x].c;
int m=(t[x].l+t[x].r)/2,ls=t[x].ls,rs=t[x].rs;
if(r<=m) return fmax(ls,l,r);
else if(l>m) return fmax(rs,l,r);
else return max(fmax(ls,l,m),fmax(rs,m+1,r));
}
void xg(int x,int y,ll k)
{
if(t[x].l==t[x].r) { t[x].c=k; return ; }
int m=(t[x].l+t[x].r)/2,ls=t[x].ls,rs=t[x].rs;
if(y<=m) xg(ls,y,k);
else xg(rs,y,k);
t[x].c=max(t[ls].c,t[rs].c);
}
int main()
{
int n,ed=0; ll d,m=0,x;char s[10];
scanf("%d %lld",&n,&d);
bt(1,mx);
while(n--)
{
scanf("%s",s+1); scanf("%lld",&x);
if(s[1]=='Q')
{
printf("%lld\n",m=fmax(1,ed-x+1,ed));
}
else
{
xg(1,++ed,(x+m)%d);
}
}
return 0;
}