Description
Description
在抗日战争中,广泛地在华北平原进行了隧道战。一般来说,通过隧道连接的村庄在一条线上。除了两端之外,每个村都与两个相邻的村庄直接相连。
Input
入侵者通常对一些村庄进行攻击,并摧毁了其中的隧道部分。八路军指挥官要求隧道和村庄的最新连接状态。如果一些村庄被严重隔离,必须立即恢复连接!
Output
输入的第一行包含两个正整数n,m(n,m≤50000)表示村庄和事件的数量。接下来的m行中的每一行描述一个事件。
有以下不同格式描述的三种不同的事件:
D x:第x个村被毁。
Q x:陆军指挥部要求第x个村直接或间接连接的村庄数量包括自己。
R:最后被破坏的村庄被重建。
Sample Input
7 9
D 3
D 6
D 5
Q 4
Q 5
R
Q 4
R
Q 4
Sample Input
1
0
2
4
暴力,一个set记录毁掉的点
#include <iostream>
#include <cstdio>
#include <stack>
#include <set>
#define SIZE 50010
using namespace std;
set<int> st;
stack<int> stk;
set<int>::iterator it;
int n;
int find(int x) // 求该位置的处在的联通块的节点个数
{
int t;
if (!st.size()) // 全部完好
{
return n;
}
if (x < *st.begin()) // 在第一个被损坏的节点前
{
return *st.begin() - 1;
}
it = st.end();
--it;
if (x > *it) // 在最后一个被损坏的节点后
{
return n - *it;
}
for (it = st.begin(); it != st.end(); ++it) // 两个被损坏的节点中间
{
if (*it > x)
{
t = *it;
break;
}
}
--it;
return t - *it - 1;
}
int main(void)
{
int m, i, x;
char ch;
scanf("%d%d", &n, &m);
while (m--)
{
cin >> ch;
if (ch == 'D')
{
scanf("%d", &x);
st.insert(x);
stk.push(x);
}
else if (ch == 'Q')
{
scanf("%d", &x);
if (st.count(x)) // 被毁,特判
{
printf("0\n");
}
else
{
printf("%d\n", find(x));
}
}
else
{
st.erase(st.find(stk.top())); // 用堆栈找最近被毁掉的节点
stk.pop();
}
}
return 0;
}