Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

Re:用splay的话合并操作该怎么做呢?

Posted by 074100411 at 2009-09-30 18:11:23 on Problem 2985
In Reply To:用splay的话合并操作该怎么做呢? Posted by:SherlockBourne at 2008-09-02 13:40:42
我也是这样做的,没TLE,O(∩_∩)O哈哈~
//注意:调用set()初始化
#include<iostream>
#include<cstring>
using namespace std;

const int BSTNC = 200005;
typedef int nit;
struct Node
{
	nit v;
	Node *father,*son[2];
	int tc;//子树有效的NIT数目
	int cc;//当前结点有效的NIT数目
};
struct BST
{
	Node tsave[BSTNC];		//代表储存结构的真实数组,给可能在BST出现的结点数目
	int tused;			    //BST中结点的数目,包括已经删除的虚假结点
	Node *root;			    //根结点的位置
	void Insert(nit v);		//插入值为v的结点
	void Delete(Node *p);	//删除位置在p的结点,假删除
	bool Delete(nit v);		//删除值为v的结点,假删除,返回删除成功否
	Node *find(nit v);		//找到值为v对应的位置,0表示不存在
	Node *findk(int k);		//找到第k小元素的位置,0表示不存在
	int rank(nit v);		//返回小于v的个数+1
	Node *pre(nit v);		//在结点值不重复的时候有效,调用时需要保证v存在,返回v的前趋,0表示不存在
	Node *nex(nit v);		//在结点值不重复的时候有效,调用时需要保证v存在,返回v的后继,0表示不存在
	int Tc(Node *p){return p?p->tc:0;}
	void rotate(Node *p,int w); //w=0表示左旋,w=1表示右旋
	void splay(Node *p);        //伸展
	void set(){memset(tsave,0,sizeof(Node)*BSTNC);tused=0;root=0;}
};
void BST::rotate(Node *A,int w)
{
	Node *B=A->father;
	B->tc = B->tc - A->tc + Tc(A->son[w]);
	A->tc = A->tc - Tc(A->son[w]) + B->tc;
	B->son[1-w]=A->son[w];
	if(A->son[w]) A->son[w]->father=B;
	A->father=B->father;
	if(B->father)
	{
		if(B==B->father->son[0]) B->father->son[0]=A;
		else B->father->son[1]=A;
	}
	B->father=A; A->son[w]=B;
}
void BST::splay(Node *A)
{
	while(A->father)
	{
		Node *B=A->father;
		if(B->father)
		{
			if(B==B->father->son[0])
			{
				if(A==B->son[0]) { rotate(B,1); rotate(A,1); }
				else { rotate(A,0); rotate(A,1); }
			}
			else
			{
				if(A==B->son[0]) { rotate(A,1); rotate(A,0); }
				else { rotate(B,0); rotate(A,0); }	
			}
		}
		else
		{
			if(A==B->son[0]) rotate(A,1);
			else rotate(A,0);
		}
		root=A;
	}
}
void BST::Insert(nit v)
{
	if(!root)
	{
		root=tsave+tused;
		tsave[tused].cc=tsave[tused].tc=1;
		tsave[tused++].v=v;
		return ;
	}
	Node *cur=root,*last;
	while(cur)
	{
		last=cur;
		cur->tc++;
		if(v==cur->v)
		{
			cur->cc++;
			return;
		}
		if(v<cur->v) cur=cur->son[0];
		else cur=cur->son[1];
	}
	cur=tsave+tused;
	last->son[v>last->v]=cur;
	cur->father=last;
	cur->cc=cur->tc=1;
	tsave[tused++].v=v;
	splay(cur);
}
void BST::Delete(Node *p)
{
	p->cc--;
	while(p)
	{
		p->tc--;
		p=p->father;
	}
}
bool BST::Delete(nit v)
{
	Node *p;
	if(p=find(v))
	{
		Delete(p);
		splay(p);
		return 1;
	}
	return 0;
}
Node *BST::find(nit v)
{
	Node *cur=root;
	while(cur)
	{
		if(v==cur->v) return cur->cc?cur:0;
		if(v<cur->v) cur=cur->son[0];
		else cur=cur->son[1];
	}
	return 0;
}
Node *BST::findk(int k)
{
	if(k<=0) return 0;
	if(k>root->tc) return 0;
	Node *cur=root;
	int c;
	while(cur)
	{
		c=Tc(cur->son[0]);
		if(k<=c) cur=cur->son[0];
		else if(k<=c+cur->cc) return cur;
		else
		{
			k-=c+cur->cc;
			cur=cur->son[1];
		}
	}
	return 0;
}
int BST::rank(nit v)
{
	Node *cur=root;
	int re=0,c;
	while(cur)
	{
		c=Tc(cur->son[0]);
		if( v==cur->v )
			return re+1+c;
		if( v<=cur->v )
			cur=cur->son[0];
		else 
		{
			re+=c+cur->cc;
			cur=cur->son[1];
		}
	}
	return re+1;
}
Node *BST::pre(nit v)
{
	int k=rank(v);
	return findk(k-1);
}
Node *BST::nex(nit v)
{
	int k=rank(v);
	return findk(k+1);
}
BST bst;
int belg[BSTNC];
int num[BSTNC];
int find( int x )
{
    int t, _x=x;
 
    while( belg[_x]!=_x )
        _x = belg[_x];
    while( belg[x]!=x )
    {
        t = belg[x];
        belg[x] = _x;
        x = t;
    }
    return _x;
}
int main()
{
	int i,n,m,a,b,c,u,v;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		bst.set();
		for(i=1;i<=n;++i) bst.Insert(1);
		for(i=1;i<=n;++i){ belg[i]=i;num[i]=1;}
		while(m--)
		{
			scanf("%d",&c);
			if(c==0)
			{
				scanf("%d%d",&a,&b);
				u=find(a);
				v=find(b);
				if(u!=v)
				{
					bst.Delete(num[u]);
					bst.Delete(num[v]);
					belg[u]=v;
					num[v]+=num[u];
					bst.Insert(num[v]);
					n--;
				}
			}
			else
			{
				scanf("%d",&a);
				printf("%d\n",bst.findk(n-a+1)->v);
			}
		}
	}

	return 0;
}



Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator