BZOJ 2733: [HNOI2012]永无乡 (Treap+启发式合并)
2017-01-06 14:54
567 查看
BZOJ 2733: [HNOI2012]永无乡
题目概述:
n座岛屿,给出m座桥连接不同的两座岛屿.现在有两种操作:
1.在两座不同岛屿间架设一座桥梁.
2.询问某一岛屿与之相连的岛屿(包括该岛屿)中重要度第k小的岛屿编号,若不存在,为-1.
输出所有第二种操作的答案.
题目分析:
先建n棵Treap实现第二种操作.对于两棵Treap的合并,采用启发式合并,选择将节点数少的一个一个插入到节点数多的.既然要将一棵树的所有结点插到另一棵树里,可以选择dfs遍历一遍.
再用并查集维护每个结点所在集合.
代码:
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; const int maxn=100000+10; char readchar() { char ch=getchar(); while(ch<'A'||ch>'Z') ch=getchar(); return ch; } struct Node { Node* ch[2]; int key,rnd,sz,id; Node(){} Node(int key,int id):key(key),id(id){rnd=rand();sz=1;ch[0]=ch[1]=NULL;} void update() { sz=1; if(ch[0]) sz+=ch[0]->sz; if(ch[1]) sz+=ch[1]->sz; } }*root[maxn],*pool[maxn]; int top; void init() {top=0;for(int i=0;i<maxn;i++) pool[i]=new Node();} Node* new_node() {return pool[top++];} void del_node(Node* &u) {pool[--top]=u;u=NULL;} void rotate(Node* &u,int d) { Node* v=u->ch[d^1];u->ch[d^1]=v->ch[d];v->ch[d]=u; u->update();(u=v)->update(); } void insert(Node* &u,Node v) { if(!u) { u=new_node();(*u)=v; return ; } int d=v.key>u->key; insert(u->ch[d],v);++(u->sz); if(u->rnd>u->ch[d]->rnd) rotate(u,d^1); } #define lc (u->ch[0]) #define rc (u->ch[1]) int find_id(Node* u,int rnk) { while(u) { int d=lc?lc->sz:0; if(rnk<=d) u=lc; else if(rnk>d+1) rnk-=d+1,u=rc; else return u->id; } return -1; } int fa[maxn]; int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);} void dfs(Node* &A,Node* &B) {//dfs遍历一遍B树,将其所有结点插入A树 if(!B) return ; if(B->ch[0]) dfs(A,B->ch[0]); if(B->ch[1]) dfs(A,B->ch[1]); insert(A,*B);del_node(B); } void merge(int x,int y) {//启发式合并 int fx=find(x),fy=find(y); if(fx==fy) return ; if(root[fx]->sz<root[fy]->sz) swap(x,y),swap(fx,fy); dfs(root[fx],root[fy]);fa[fy]=fx; } int main() { init(); int n,m,k,u,v,q; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&k);fa[i]=i; insert(root[i],Node(k,i)); } while(m--) { scanf("%d%d",&u,&v); merge(u,v); } scanf("%d",&q); while(q--) { if(readchar()=='B') { scanf("%d%d",&u,&v); merge(u,v); } else { scanf("%d%d",&u,&v); printf("%d\n",find_id(root[find(u)],v)); } } 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]永无乡 Splay启发式合并
- 【BZOJ 2733】【HNOI 2012】永无乡【treap启发式合并】
- bzoj 2733 [HNOI2012]永无乡 splay启发式合并
- BZOJ 2733 HNOI 2012 永无乡 平衡树启发式合并
- [并查集+启发式合并]BZOJ 2733——[HNOI2012]永无乡
- bzoj 2733: [HNOI2012]永无乡(线段树启发式合并)
- 【BZOJ 2733】 [HNOI2012]永无乡|Splay启发式合并
- bzoj 2733: [HNOI2012]永无乡(线段树启发式合并)
- BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]
- BZOJ 2733 [HNOI2012] 永无乡 [splay+启发式合并做法]
- [BZOJ][平衡树+启发式合并][替罪羊树]2733: [HNOI2012]永无乡
- bzoj 2733: [HNOI2012]永无乡 (线段树合并)[省选计划系列]
- BZOJ 2733 [HNOI2012] 永无乡 Treap
- 【BZOJ 2733】【HNOI 2012】永无乡 Splay启发式合并
- BZOJ 2733 [HNOI2012]永无乡 Treap + 并查集