POJ2892 HDU1540 Tunnel Warfare(Splay)

原创 2015年11月21日 15:01:18

有n个村庄连成一排,m个指令。D x为破坏村庄x,Q x为查询与x联通的村庄的个数,R为恢复上一个被破坏的村庄。

用一棵splay树,每次破坏一个村庄,就插入它的编号;查询的时候找到前驱后继(当然,如果该村庄已经被破坏,直接输出0就好了);恢复村庄时再删除这个节点。注意为了方便查询,我们先插入0和n+1。

#include<cstdio>
#include<cctype>
#include<stack>
#define MAXN 50010
using namespace std;
int n,m,fa[MAXN],ch[MAXN][2],v[MAXN],root,cnt,num;
stack<int> S;
char ops[3];
bool instack[MAXN];
void rotate(int x)
{
	int y = fa[x],z = fa[y],f = (ch[y][1]==x);
	ch[y][f] = ch[x][!f];
	if(ch[y][f]) fa[ch[y][f]] = y;
	ch[x][!f] = y,fa[y] = x;
	fa[x] = z;
	if(z) ch[z][ch[z][1]==y] = x;
}
void splay(int x,int goal)
{
	for(int y; (y=fa[x])!=goal; rotate(x))
	{
		int z = fa[y];
		if(z != goal)
		{
			if((ch[z][1]==y)==(ch[y][1]==x)) rotate(y);
			else rotate(x);
		}
	}
	if(goal == 0) root = x;
}
void insert(int val)
{
	int x = root,y = 0,f = 0;
	while(x != 0)
	{
		if(v[x] == val) break;
		f = (v[x]<val);
		y = x;
		x = ch[x][f];
	}
	if(x == 0) 
	{	
		x = ++cnt;
		v[x] = val;
		fa[x] = y;
		if(y) ch[y][f] = x;
	}
	splay(x,0);
}
int nxt(int val,bool flag)
{
	int x = root,y = 0;
	while(x != 0)
	{
		y = x;
		if(v[x] == val) break;
		x = ch[x][v[x]<val];
	}
	if((v[y]>val&&flag==1)||(v[y]<val&&flag==0)) return y;
	splay(y,0);
	int tmp = ch[y][flag];
	while(ch[tmp][!flag])
		tmp = ch[tmp][!flag];
	return tmp;
}
void del(int val)
{
	int x = nxt(val,0),y = nxt(val,1);
	splay(x,0);
	splay(y,x);
	int z = ch[y][0];
	if(z)
	{
		ch[y][0] = 0;
		splay(y,0);
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	insert(0);
	insert(n+1);
	while(m--)
	{
		scanf("%s",ops);
		if(ops[0] == 'D')
		{
			scanf("%d",&num);
			insert(num);
			S.push(num);
			instack[num] = 1;
		}
		else if(ops[0] == 'Q')
		{
			scanf("%d",&num);
			if(instack[num]) printf("0\n");
			else
			{	
				int x = v[nxt(num,0)],y = v[nxt(num,1)];
				printf("%d\n",y-x-1);
			}
		}
		else 
		{
			if(!S.empty())
			{
				del(S.top());
				instack[S.top()] = 0;
				S.pop();
			}
		}
	}
}


版权声明:本文的版权归作者和CSDN博客所有,未经作者同意严禁转载,否则将追究其法律责任!

相关文章推荐

hdu 1540/POJ 2892 Tunnel Warfare 【线段树区间合并】

Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) 链...

HDU 1540 && POJ 2892 Tunnel Warfare (线段树,区间合并).

~~~~ 第一次遇到线段树合并的题,又被律爷教做人。TAT. ~~~~ 线段树的题意都很好理解吧。。 题目链接: http://acm.hdu.edu.cn/showproblem.php?...

hdu1540 && POJ2892 Tunnel Warfare

【比赛提醒】BestCoder 你报名了吗?(点击报名) 【科普】什么是BestCoder?如何参加? Tunnel Warfare Time Limit: 4000/2000 MS (Ja...

poj 2892 || hdu 1540 Tunnel Warfare

又是找区间最长的什么什么的。和hotel前期处理差不多。都需要记录从左边开始的连续的最大值,从右边开始的连续最大值,以及整个区间的最大值。 不同的是,这个题的R D操作都是基于点的操作,所以不需要用...

poj2892 同hdu1540 Tunnel Warfare 线段树

http://poj.org/problem?id=2892 题意:在抗日时期,我方经常采用地道战,地雷战,麻雀战来袭扰日军。  现在n个村子一开始是全部联通的,假设成一条直线。  给出3种操作...

POJ2892 HDU 1540 Tunnel Warfare, 树状数组

利用树状数组的find_k_th实现找到sum为k的最小位置,  时间复杂度为O(log(n)) /***********************************************...
  • neofung
  • neofung
  • 2012年01月29日 23:54
  • 918

POJ 2892 hdu 1540 Tunnel Warfare 线段树 (区间合并)

这个题目的大意就是,求某个点所在的最长连续区间 区间合并此类题目的通常做法都是开3个变量,区间最大值,从左往右的连续区间长度,从右往左的连续区间长度。 然后更新的时候更新到点就行了。 查询的时候...

hdu1540&poj2892Tunnel Warfare(线段树单点更新)

->题目请戳这 和这-> 题目大意,给n个点表示n个村庄,一开始都是相连的,现在有3种操作:Q x,查询第与第x个村庄相连的村庄个数;D x,摧毁掉第x个村庄;R  恢复刚摧毁的村庄。 题目分析:每个...

POJ 2892 Tunnel Warfare && HDOJ 1540 (线段树)

POJ  http://poj.org/problem?id=2892 单case HDOJ http://acm.hdu.edu.cn/showproblem.php?pid=1540 多ca...
  • ivapple
  • ivapple
  • 2012年09月07日 22:58
  • 344

【POJ 2892】 Tunnel Warfare(树状数组+二分)

【POJ 2892】 Tunnel Warfare(树状数组+二分) Time Limit: 1000MS   Memory Limit: 131072K To...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ2892 HDU1540 Tunnel Warfare(Splay)
举报原因:
原因补充:

(最多只允许输入30个字)