HDU - 1540 Tunnel Warfare (奇妙的解法)

题目描述:
During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast areas of north China Plain. Generally speaking, villages connected by tunnels lay in a line. Except the two at the ends, every village was directly connected with two neighboring ones.

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
The first line of the input contains two positive integers n and m (n, m ≤ 50,000) indicating the number of villages and events. Each of the next m lines describes an event.

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
Output the answer to each of the Army commanders’ request in order on a separate line.
Sample Input
7 9
D 3
D 6
D 5
Q 4
Q 5
R
Q 4
R
Q 4
Sample Output
1
0
2
4

题意:

给出n个村庄,这n个村庄在一条线上,相邻的村庄相连。
m个操作。操作有三种。
第一种D num,将第num的村庄摧毁。
第二种,Q num,查询与第num的村庄直接或间接相连的村庄。
第三种,R,重建最后被摧毁的那个村庄。

解题思路:

1.正解据说是线段树。
.
2.首先,用栈把摧毁的村庄依次压入栈中。重建,就是删除栈顶。
  然后,就是D,摧毁。我们用set存储被摧毁的村庄。
  因为set自动排序,那么我们要找一个村庄与几个村庄相连,就相当与找它
  左右最近被摧毁的村庄,相减就是答案。找的时候用二分。

HDU - 1540 Tunnel Warfare (奇妙的解法)_第1张图片

如图,我们把3,5,6,加入set,找4,那么就找他的左右的被摧毁村庄下标为,3和5,几个相连就可以算出。

如果查1,我们能找到它右边是3,但是左边没有。所以开始把0和n+1存入set。
如果查询的已经被摧毁,直接输出0.

代码:

# include 
# include 
# include 
# include 
using namespace std; 
int main()
{
	int tem;
	int n,m;
	char c[5];
	while(~scanf("%d %d",&n,&m))
	{
		set se;
		stack st;
		se.insert(0);
		se.insert(n+1);
		while(m--)
		{
			scanf("%s",c);
			if(c[0] == 'D'){
				scanf("%d",&tem);
				se.insert(tem);
				st.push(tem);
			}else if(c[0] == 'Q'){
				scanf("%d",&tem);
				if(se.count(tem))
				{
					printf("0\n");
				}else{
					int l = *(--se.upper_bound(tem));
					int r = *se.upper_bound(tem);
					printf("%d\n",r-l-1);
				}
			}else{
				int tt = st.top();
				st.pop();
				se.erase(se.find(tt));
			}
		}
	}
	return 0;
}

无耻求赞

你可能感兴趣的:(个人算法晋升之路,hdu)