BZOJ 2733 [HNOI2012] 永无乡 Treap
2016-12-31 08:29
351 查看
题目大意:给出n个只有一个元素的集合,有以下操作:集合合并,查集合第k小。
查询集合内第k小,平衡树可以搞。
合并怎么办?
启发式合并。暴力拆解一个size比较小的,保证每个点至多被拆log(n)次。
如果俩点在一个集合里就不能再合并了否则会RE
查询集合内第k小,平衡树可以搞。
合并怎么办?
启发式合并。暴力拆解一个size比较小的,保证每个点至多被拆log(n)次。
如果俩点在一个集合里就不能再合并了否则会RE
#include <cstdio> #include <cstdlib> #define N 100005 using namespace std; struct Point { int ord,val; Point(int x=0,int y=0):ord(x),val(y){} bool operator < (const Point &rhs) const {return val<rhs.val;} bool operator == (const Point &rhs) const {return val==rhs.val;} }; struct Node { Node* ch[2]; int s,r; Point v; int cmp(Point x) { if(x==v) return -1; return x < v ? 0 : 1; } void maintain() { s=ch[0]->s+ch[1]->s+1; return ; } Node(Point); }*null=new Node(Point(0,0)),*treap ; Node :: Node(Point x):v(x){ r=rand(); s=null ? 1 : 0; ch[0]=ch[1]=null;} void Rotate(Node*& o,int d) { Node* k=o->ch[d^1]; o->ch[d^1]=k->ch[d]; k->ch[d]=o; o->maintain(); k->maintain(); o=k; return ; } void Insert(Node*& o,Point x) { if(o==null) {o=new Node(x); return ;} int d=o->cmp(x); Insert(o->ch[d],x); if(o->ch[d]->r > o->r) Rotate(o,d^1); o->maintain(); return ; } void Merge(Node*& o,Node*& x) { if(o==null) return ; Merge(o->ch[0],x); Merge(o->ch[1],x); Insert(x,o->v); delete o; o=null; return ; } int Kth(Node* o,int x) { if(x > o->s || x<1 || o==null) return -1; if(o->ch[0]->s+1 == x) return o->v.ord; if(o->ch[0]->s+1 > x) return Kth(o->ch[0],x); return Kth(o->ch[1],x-o->ch[0]->s-1); } int pa ; int root(int x) {return pa[x]==x ? pa[x] : pa[x]=root(pa[x]);} int main() { null->ch[0]=null->ch[1]=null; int n,m,x,y; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&x) , treap[i]=new Node(Point(i,x)) , pa[i]=i; while(m--) { scanf("%d%d",&x,&y); int pa_x=root(x),pa_y=root(y); if(pa_x==pa_y) continue; if(treap[pa_x]->s > treap[pa_y]->s) Merge(treap[pa_y],treap[pa_x]) , pa[pa_y]=pa_x; else Merge(treap[pa_x],treap[pa_y]) , pa[pa_x]=pa_y; } scanf("%d",&m); while(m--) { char mode[2]; scanf("%s%d%d",mode,&x,&y); int pa_x=root(x); if(mode[0]=='Q') printf("%d\n",Kth(treap[pa_x],y)); if(mode[0]=='B') { int pa_y=root(y); if(pa_x==pa_y) continue; if(treap[pa_x]->s > treap[pa_y]->s) Merge(treap[pa_y],treap[pa_x]) , pa[pa_y]=pa_x; else Merge(treap[pa_x],treap[pa_y]) , pa[pa_x]=pa_y; } } return 0; }
相关文章推荐
- BZOJ 2733([HNOI2012]永无乡-Treap启发式合并)
- BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)
- BZOJ 2733 HNOI2012 永无乡 Treap+启发式合并
- 【BZOJ 2733】[HNOI2012]永无乡 启发式合并treap
- BZOJ 2733: [HNOI2012]永无乡 (Treap+启发式合并)
- BZOJ 2733: [HNOI2012]永无乡 启发式合并treap
- BZOJ 2733 [HNOI2012]永无乡 Treap + 并查集
- 【模板】【bzoj2733】[HNOI2012]永无乡 Treap
- bzoj 2733 [HNOI2012]永无乡
- BZOJ 2733 HNOI 2012 永无乡 平衡树启发式合并
- BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]
- bzoj 2733 [HNOI2012]永无乡 并查集+平衡树
- 2733: [HNOI2012]永无乡 - BZOJ
- 【BZOJ 2733】 [HNOI2012]永无乡
- BZOJ 2733 [HNOI2012] 永无乡 [线段树+并查集做法]
- BZOJ 2733 [HNOI2012]永无乡(启发式合并+Treap+并查集)
- BZOJ 2733 2733: [HNOI2012]永无乡 平衡树启发式合并
- bzoj 2733: [HNOI2012]永无乡
- bzoj 2733: [HNOI2012]永无乡 离线+主席树
- 【并查集套可持久化线段树】【bzoj 2733】: [HNOI2012]永无乡