hdu1540
#include<cstdio>
#include<algorithm>
/*
hdu1540 求某个节点左右连续节点的个数
1、维护三个数组pre,suf,maxn 分别代表L~R区间以L开头的前缀连续节点数,以R结尾后缀连续节点数,最长连续节点数
*/
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<set>
#include<queue>
#include<stack>
using namespace std;
#define ll long long
int pre[200005],suf[200005],maxn[200005];
void build(int L,int R,int num)
{
pre[num]=suf[num]=maxn[num]=R-L+1;
if(L==R)
return;
int mid=(L+R)/2;
build(L,mid,num*2);
build(mid+1,R,num*2+1);
}
void pushup(int L,int R,int num)
{
int mid=(L+R)/2;
pre[num]=pre[num*2];
suf[num]=suf[num*2+1];
maxn[num]=max(maxn[num*2],maxn[num*2+1]);
maxn[num]=max(maxn[num],suf[num*2]+pre[num*2+1]);
if(pre[num*2]==(mid-L+1))pre[num]+=pre[num*2+1];
if(suf[num*2+1]==(R-mid))suf[num]+=suf[num*2];
}
void update(int L,int R,int num,int va,int RD)
{
if(L==R&&L==va)
{
pre[num]=suf[num]=maxn[num]=RD;
return;
}
int mid=(L+R)/2;
if(va<=mid)
{
update(L,mid,num*2,va,RD);
}
if(va>mid)
{
update(mid+1,R,num*2+1,va,RD);
}
pushup(L,R,num);
}
int query(int L,int R,int num,int va)
{
if(L==R||maxn[num]==0||maxn[num]==R-L+1)
{
return maxn[num];
}
int mid=(L+R)/2;
if(va<=mid)
{
if(va>=mid-suf[num*2]+1)return suf[num*2]+pre[num*2+1];
else return query(L,mid,num*2,va);
}
if(va>mid)
{
if(va<=mid+pre[num*2+1])return suf[num*2]+pre[num*2+1];
else return query(mid+1,R,num*2+1,va);
}
}
int main()
{
std::ios::sync_with_stdio(false);
int n,m,i,x;
char cc[10];
stack<int>q;
while(~scanf("%d %d",&n,&m))
{
while(!q.empty())
q.pop();
build(1,n,1);
for(i=0;i<m;i++)
{
scanf("%s",cc);
getchar();
if(cc[0]=='D')
{
scanf("%d",&x);
q.push(x);
update(1,n,1,x,0);
}
else if(cc[0]=='Q')
{
scanf("%d",&x);
printf("ans %d\n",query(1,n,1,x));
}
else
{
if(!q.empty())
{
update(1,n,1,q.top(),1);
q.pop();
}
}
}
}
return 0;
}