题目大意:1-n个地道,m个次操作,D代表摧毁第i个地道,Q代表查询包含第i个地道的最大连续地道数目,并输出。R代表修复最近摧毁的那个地道
解题思路:由于题目中说明R表示修复最近摧毁的那个通道,所以自然而然的想到利用栈来解决,在本题中使用数组来模拟栈操作,其次,Q代表查询包含第i个地道的最大连续地道数目,这个就表示要求求出包含在本节点在内的最大连续区间的和。在下面解题中,1表示地道未被炸毁,0表示地道被炸毁。
求最大连续区间的和的方法:维护区间中从左节点开始的最大连续区间和区间中从右节点开始的最大连续区间和,以及在这个区间中最大连续区间和
AC代码:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN = 50005;
int n,m;
int sta[MAXN],top;
struct Tree
{
int l,r;
int msm,lsm,rsm;
}tree[4*MAXN];
void Build(int i,int l,int r)
{
tree[i].l = l;
tree[i].r = r;
if(l == r)
{
tree[i].msm = tree[i].lsm = tree[i].rsm = 1;
return;
}
int mid = (l+r)>>1;
Build(i<<1,l,mid);
Build(i<<1|1,mid+1,r);
tree[i].msm = tree[i<<1].msm + tree[i<<1|1].msm;
tree[i].lsm = tree[i].rsm = tree[i].msm;
}
void Update(int i,int mem,int res)
{
if(tree[i].l == tree[i].r)
{
tree[i].msm = tree[i].lsm = tree[i].rsm = res;
return;
}
int mid = (tree[i].l+tree[i].r)>>1;
if(mem <= mid) Update(i<<1,mem,res);
else Update(i<<1|1,mem,res);
tree[i].msm = max(max(tree[i<<1].msm,tree[i<<1|1].msm),tree[i<<1].rsm+tree[i<<1|1].lsm);
if(tree[i<<1].lsm == tree[i<<1].r-tree[i<<1].l+1)
tree[i].lsm = tree[i<<1].lsm + tree[i<<1|1].lsm;
else
tree[i].lsm = tree[i<<1].lsm;
if(tree[i<<1|1].rsm==tree[i<<1|1].r-tree[i<<1|1].l+1)
tree[i].rsm = tree[i<<1|1].rsm + tree[i<<1].rsm;
else
tree[i].rsm = tree[i<<1|1].rsm;
}
int Query(int i,int mem)
{
if(tree[i].l==tree[i].r || tree[i].msm==0 || tree[i].msm == tree[i].r-tree[i].l+1)
return tree[i].msm;
int mid = (tree[i].l+tree[i].r)>>1;
if(mem <= mid)
{
if(mem >= (tree[i<<1].r-tree[i<<1].rsm+1))
return tree[i<<1].rsm + Query(i<<1|1,mid+1);
else
return Query(i<<1,mem);
}else
{
if(mem <= (tree[i<<1|1].l+tree[i<<1|1].lsm-1))
return tree[i<<1|1].lsm + Query(i<<1,mid);
else
return Query(i<<1|1,mem);
}
}
int main()
{
char ch[2];
int mem,ans;
while(~scanf("%d%d",&n,&m))
{
top = 0;
Build(1,1,n);
while(m--)
{
scanf("%s",ch);
if(ch[0]=='D')
{
scanf("%d",&mem);
sta[++top] = mem;
Update(1,mem,0);
}else
if(ch[0]=='Q')
{
scanf("%d",&mem);
ans = Query(1,mem);
printf("%d\n",ans);
}else
{
Update(1,sta[top],1);
top--;
}
}
}
return 0;
}