bzoj 2733 永无乡 Splay 启发式合并
2016-09-24 15:17
337 查看
题目大意:n(n<=10w)个点,每个点都有重要度,q(q<=30w)个操作。1.每次连接2个点。2.查询a,k;与a相连的第k重要是哪一个点,不存在输出-1。
查询可以Splay搞,修改暴力启发式合并,因为每次合并size翻倍,所以每个点最多被合并logn次。复杂度nlog²n。
查询可以Splay搞,修改暴力启发式合并,因为每次合并size翻倍,所以每个点最多被合并logn次。复杂度nlog²n。
#include<cstdio> #include<iostream> #include<cstdlib> #define maxn 100005 using namespace std; int fa[maxn]; int ch[maxn][2]; int sz[maxn]; int key[maxn]; bool dir(int x) {return x==ch[fa[x]][1];} void up(int x) {sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;} void rotate(int x) { bool b=dir(x); int y=fa[x]; int z=fa[y]; int a=ch[x][!b]; if(z)ch[z][dir(y)]=x; fa[x]=z;ch[y][b]=a; fa[y]=x;ch[x][!b]=y; if(a!=0) fa[a]=y; up(y);up(x); } void splay(int x) { while(fa[x]) { int y=fa[x];int z=fa[y]; if(z==0) rotate(x); else { bool b=dir(x); bool c=dir(y); if(b^c) {rotate(x);rotate(x);} else {rotate(y);rotate(x);} } } } int lass; void insert(int x,int k,int last) { if(k==0) { fa[x]=last; if(key[x]<key[last]) ch[last][0]=x; else ch[last][1]=x; splay(x); lass=x; return ; } if(key[x]<key[k]) insert(x,ch[k][0],k); else insert(x,ch[k][1],k); } int rank_num(int x,int k) { if(sz[ch[x][0]]+1==k) return x; if(sz[ch[x][0]]>=k) return rank_num(ch[x][0],k); return rank_num(ch[x][1],k-sz[ch[x][0]]-1); } int F[maxn]; int find(int x) {return F[x]==x?x:F[x]=find(F[x]);} void dfs(int x,int y) { int q=ch[x][0],w=ch[x][1]; ch[x][0]=0;ch[x][1]=0; insert(x,y,0); if(q)dfs(ch[x][0],lass); if(w)dfs(ch[x][1],lass); } char s[3]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { sz[i]=1; scanf("%d",&key[i]); F[i]=i; } int x,y; for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y); if(find(x)!=find(y)) { F[find(x)]=find(y); splay(x);splay(y); if(sz[x]>sz[y])dfs(y,x); else dfs(x,y); } } int q;scanf("%d",&q); char c; for(int i=1;i<=q;i++) { scanf("%s",s); scanf("%d%d",&x,&y); if(s[0]=='B') { if(find(x)!=find(y)) { F[find(x)]=find(y); splay(x);splay(y); if(sz[x]>sz[y]) dfs(y,x); else dfs(x,y); } } if(s[0]=='Q') { splay(x); if(y>sz[x]) printf("-1\n"); else printf("%d\n",rank_num(x,y)); } } return 0; }
相关文章推荐
- BZOJ[2733][HNOI2012]永无乡 Splay启发式合并
- 【BZOJ 2733】 [HNOI2012]永无乡|Splay启发式合并
- BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]
- 【splay启发式合并】bzoj 2733 永无乡
- bzoj 2733 [HNOI2012]永无乡 splay启发式合并
- [线段树 启发式合并] BZOJ 2733 永无乡
- BZOJ 2733 [HNOI2012] 永无乡 [splay+启发式合并做法]
- bzoj 2733 永无乡 线段树启发式合并
- [并查集+启发式合并]BZOJ 2733——[HNOI2012]永无乡
- BZOJ 2733: [HNOI2012]永无乡 启发式合并treap
- 【BZOJ 2733】【HNOI 2012】永无乡 Splay启发式合并
- 【BZOJ 2733】[HNOI2012]永无乡 启发式合并treap
- BZOJ 2733: [HNOI2012]永无乡 (Treap+启发式合并)
- bzoj 2733 Splay 启发式合并,名次树
- BZOJ 2733 HNOI2012 永无乡 Treap+启发式合并
- bzoj 2733: [HNOI2012]永无乡(线段树启发式合并)
- BZOJ 2733([HNOI2012]永无乡-Treap启发式合并)
- BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)
- bzoj 2733(splay启发式合并)
- bzoj 2733: [HNOI2012]永无乡(线段树启发式合并)