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