Description
Frequently the invaders launched attack on some of the villages and destroyed the parts of tunnels in them. The Eighth Route Army commanders requested the latest connection state of the tunnels and villages. If some villages are severely isolated, restoration of connection must be done immediately!
Input
There are three different events described in different format shown below:
D x: The x-th village was destroyed.
Q x: The Army commands requested the number of villages that x-th village was directly or indirectly connected with including itself.
R: The village destroyed last was rebuilt.
Output
Sample Input
Sample Output
#include"stack"
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
#define MAXN 500005
#define lson id << 1
#define rson id << 1 | 1
int n,m;
struct TREE
{
int l,r;
int lc,rc,mc;
}tree[MAXN << 2];
stack < int > ST ;
void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].lc = tree[id].rc = tree[id].mc = r - l + 1;
if(l != r)
{
int mid = (l + r) >> 1;
build(lson,l,mid);
build(rson,mid+1,r);
}
}
void update(int id,int pos,int op)
{
if(tree[id].l == tree[id].r)
{
if(op) //毁坏
{
tree[id].mc = tree[id].lc = tree[id].rc = 0;
}
else //重建
{
tree[id].mc = tree[id].lc = tree[id].rc = 1;
}
}
else
{
int mid = (tree[id].r + tree[id].l) >> 1;
if(pos <= mid)
{
update(lson,pos,op);
}
else
{
update(rson,pos,op);
}
tree[id].lc = tree[lson].lc; //左区间
tree[id].rc = tree[rson].rc; //右区间
tree[id].mc = max((tree[lson].rc + tree[rson].lc),max(tree[lson].mc,tree[rson].mc));
//父结点的最大连续区间为左子树的最大、右子树最大、左右子树合并区间中的一个
if(tree[lson].mc == tree[lson].r - tree[lson].l + 1) //左子树区间满
{
tree[id].lc += tree[rson].lc; //父亲左区间加上右子树的左区间
}
if(tree[rson].mc == tree[rson].r - tree[rson].l + 1) //右子树区间满
{
tree[id].rc += tree[lson].rc; //父亲右区间加上左子树的右区间
}
}
}
int query(int id,int num)
{
if(tree[id].l == tree[id].r || tree[id].mc == 0 || tree[id].mc == tree[id].r - tree[id].l + 1)
//如果为叶子结点或者区间为空(满),则不用继续查询
{
return tree[id].mc;
}
int mid = (tree[id].l + tree[id].r) >> 1;
if(num <= mid) //查左子树
{
if(num >= tree[lson].r - tree[lson].rc + 1) //num>=左子树右边连续区间的右边界值
{
return query(lson,num) + query(rson,mid+1); //与右子树左区间有联系
}
else
{
return query(lson,num);
}
}
else //查右子树
{
if(num <= tree[rson].l + tree[rson].lc - 1) //num<=右子树左边连续区间的右边界值
{
return query(rson,num) + query(lson,mid); //与左子树右区间有关系
}
else
{
return query(rson,num);
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
while(! ST.empty())
{
ST.pop();
}
build(1,1,n);
while(m--)
{
char str[5];
int num;
scanf("%s",str);
if(str[0] == 'D') //1表示毁坏
{
scanf("%d",&num);
ST.push(num);
update(1,num,1);
}
else if(str[0] == 'R' && !ST.empty()) //0表示重建,考虑了一下没有毁坏但是却出现重建指令的可能
{
int temp = ST.top();
ST.pop();
update(1,temp,0);
}
else
{
scanf("%d",&num);
printf("%d\n",query(1,num));
}
}
}
return 0;
}