| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
Re:用splay的话合并操作该怎么做呢?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: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator