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;
}