线段树维护村庄状态。
1表示未摧毁
0表示摧毁。
问最大连续村庄,只需要求左右最近摧毁村庄位置相减即可。//包括自身的村庄
以上过程也可以用set进行维护,即:set存被摧毁村庄id。用二分快速查找。
//KX
#include
using namespace std;
typedef long long ll;
typedef double db;
//unordered_mapmp;
const int M= 1e5+7;
#define ls o*2
#define rs o*2+1
#define m (l+r)/2
//单点更新,维护最小值,区间查询,区间最右边0,和最左边的0的坐标。
int mn[M<<2],a[M];
int n;
void pu(int o)
{
mn[o]=min(mn[ls],mn[rs]);
}
void bd(int o,int l,int r)
{
if(l==r)
{
mn[o]=1;
if(l==0||l==n+1)mn[o]=0;
return;
}
bd(ls,l,m);
bd(rs,m+1,r);
pu(o);
}
void up(int o,int l,int r,int x,int d)
{
if(l==r)
{
mn[o]=d;
return ;
}
if(x<=m)up(ls,l,m,x,d);
else up(rs,m+1,r,x,d);
pu(o);
}
int pos,f;
void qul(int o,int l,int r,int x)
{
if(f||rx)return ;
if(l==r)
{
if(mn[o]==1)return;
pos=l;
f=true;
return ;
}
if(mn[rs]==0) qur(rs,m+1,r,x);
qur(ls,l,m,x);
}
int qu(int o,int l,int r,int x)
{
if(l==r)
return mn[o];
if(x<=m)return qu(ls,l,m,x);
return qu(rs,m+1,r,x);
}
int sk[M];
int main()
{
int q;
while(~scanf("%d%d",&n,&q))
{
char s[3];
int x;
int N=n+1;
bd(1,0,N);
int top=0;
for(int i=1;i<=q;i++)
{
// puts("ooooooooooooooo");
scanf("%s",s);
if(s[0]=='D')
{
scanf("%d",&x);
up(1,0,N,x,0);
// printf("======= %d %d\n",x,qu(1,1,n,x));
sk[++top]=x;
}
else if(s[0]=='Q')
{
scanf("%d",&x);
if(qu(1,0,N,x)==0)
{
printf("%d\n",0);
continue;
}
f=false;
int l,r;
qul(1,0,N,x);//右边区间 最左边的0的位置
r=pos;
f=false;
qur(1,0,N,x);//左边区间 最右边的0的位置
l=pos;
printf("%d\n",r-l-1);
}
else
{
if(top==0)continue;
up(1,0,N,sk[top],1);
top--;
}
}
}
return 0;
}