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博客所有,未经作者同意严禁转载,否则将追究其法律责任!

POJ2892 HDU 1540 Tunnel Warfare, 树状数组

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

hdu1540 && POJ2892 Tunnel Warfare

【比赛提醒】BestCoder 你报名了吗?(点击报名) 【科普】什么是BestCoder?如何参加? Tunnel Warfare Time Limit: 4000/2000 MS (Ja...
  • Guard_Mine
  • Guard_Mine
  • 2015年01月11日 12:40
  • 617

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

Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
  • qiqi_skystar
  • qiqi_skystar
  • 2015年12月17日 10:45
  • 1372

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

【POJ 2892】 Tunnel Warfare(树状数组+二分) Time Limit: 1000MS   Memory Limit: 131072K To...
  • ChallengerRumble
  • ChallengerRumble
  • 2016年02月26日 17:23
  • 1406

HDU1540:Tunnel Warfare(线段树区间合并)

Problem Description During the War of Resistance Against Japan, tunnel warfare was carried out exte...
  • libin56842
  • libin56842
  • 2013年11月03日 15:05
  • 5507

poj2892 同hdu1540 Tunnel Warfare 线段树

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

POJ2892 Tunnel Warfare (平衡树)

传送门 思路:当炸掉一个城市的时候,就把这个城市放入平衡树中(最开始的时候放入n+1和0),查询的时候输出这个数的后继-前驱-1,这就是答案。代码(写的Splay):#include #define...
  • geng4512
  • geng4512
  • 2015年11月22日 16:17
  • 603

HDU1540 Tunnel Warfare

Problem Description During the War of Resistance Against Japan, tunnel warfare was carried out ex...
  • mowayao
  • mowayao
  • 2014年05月06日 13:08
  • 583

poj2892——Tunnel Warfare

...(poj可过,hdu过不去,郁闷!)#include #include #include using namespace std; #define maxn 50005 int ans...
  • k1246195917
  • k1246195917
  • 2011年02月27日 16:19
  • 349

STL hdu1540 Tunnel Warfare

虽然这题在线段树的专题里面,,然而我并不觉得需要用线段树 维护一个set和stack,set里面的数字表示被摧毁的村庄节点,stack里面存放的是被摧毁的村庄节点 初始化,将0和n+1插入...
  • qwb492859377
  • qwb492859377
  • 2015年08月08日 13:57
  • 684
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ2892 HDU1540 Tunnel Warfare(Splay)
举报原因:
原因补充:

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