[并查集+启发式合并]BZOJ 2733——[HNOI2012]永无乡
来源:互联网 发布:c语言排队系统 编辑:程序博客网 时间:2024/06/04 18:01
Ps:又水听博主解释一下:昨天模拟赛遇到启发式的裸题,愣是打成左偏树的合并,惭愧惭愧。于是今天找到裸题练习一下。
题目梗概
有n个节点,每个节点有一个独一无二的权值。
合并一些节点。
询问一个节点所在联通块的权值第k大的节点,不存在则输出-1。
解题思路
什么SB题
这显然是平衡树的一道模板题,并且涉及到启发式合并。
启发式合并听着高大上其实是非常暴力过程。
当两棵平衡树合并时,把节点数较少的平衡树拆开,一个个插入到节点数较多的平衡树。
效率:最坏的情况是两棵树一样大,那么每个节点最多插入了
博主写的是treap,两个
还有因为每次需要获取每个联通块的祖先,需要并查集搞一搞。
#include<cstdio>#include<algorithm>using namespace std;const int maxn=100005;struct jz{ int x,r,s,id; jz* son[2];};jz a[maxn*100],*null=a,*til=a,*ro[maxn];int n,m,f[maxn],Q;inline int _read(){ int num=0;char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9') num=num*10+ch-48,ch=getchar(); return num;}jz* newnode(int x,int id){ til++;til->x=x;til->s=1;til->id=id;til->r=rand(); til->son[0]=til->son[1]=null; return til;}void updata(jz* x){x->s=x->son[0]->s+x->son[1]->s+1;}void turn(jz* &x,int d){ jz* t=x->son[d];x->son[d]=t->son[d^1];t->son[d^1]=x; t->s=x->s;updata(x);x=t;}void Insert(jz* &x,int y,int id){ if (x==null){x=newnode(y,id);return;} x->s++; if (y<x->x){ Insert(x->son[0],y,id); if (x->son[0]->r<x->r) turn(x,0); }else{ Insert(x->son[1],y,id); if (x->son[1]->r<x->r) turn(x,1); }}int kth(jz* x,int k){ if (x->son[0]->s<k&&k<=x->son[0]->s+1) return x->id;else if (k<=x->son[0]->s) return kth(x->son[0],k);else return kth(x->son[1],k-x->son[0]->s-1);}void merge(jz* &x,jz* y){ if (y==null) return; Insert(x,y->x,y->id); merge(x,y->son[0]);merge(x,y->son[1]);}int get(int x){ if (f[x]==x) return x; f[x]=get(f[x]); return f[x];}void add(int x,int y){ if (ro[x]->s<ro[y]->s) swap(x,y); if (x!=y) merge(ro[x],ro[y]),f[y]=x;}int main(){ freopen("exam.in","r",stdin); freopen("exam.out","w",stdout); n=_read(),m=_read(); for (int i=1;i<=n;i++) ro[i]=newnode(_read(),i),f[i]=i; for (int i=1;i<=m;i++){ int x=get(_read()),y=get(_read()); if (x||y) add(x,y); } Q=_read(); while (Q--){ char ch=getchar(); while (ch!='Q'&&ch!='B') ch=getchar(); if (ch=='Q'){ jz* fa=ro[get(_read())];int y=_read(); if (fa->s<y) printf("-1\n");else printf("%d\n",kth(fa,y)); }else{ int x=get(_read()),y=get(_read()); add(x,y); } } return 0;}
阅读全文
0 0
- [并查集+启发式合并]BZOJ 2733——[HNOI2012]永无乡
- BZOJ_P2733/Codevs_P1477 [HNOI2012]永无乡(Treap+启发式合并+并查集)
- [BZOJ2733][HNOI2012]永无乡(并查集+splay启发式合并)
- BZOJ 2733 HNOI2012 永无乡 Treap+启发式合并
- 【BZOJ 2733】 [HNOI2012]永无乡|Splay启发式合并
- bzoj 2733 [HNOI2012]永无乡 splay启发式合并
- 【BZOJ 2733】[HNOI2012]永无乡 启发式合并treap
- BZOJ 2733: [HNOI2012]永无乡 (Treap+启发式合并)
- BZOJ 2733([HNOI2012]永无乡-Treap启发式合并)
- BZOJ 2733 2733: [HNOI2012]永无乡 平衡树启发式合并
- bzoj 2733: [HNOI2012]永无乡(splay+启发式合并)
- Bzoj 2733: [HNOI2012]永无乡(线段树+启发式合并)
- BZOJ 2733 [HNOI2012] 永无乡 [splay+启发式合并做法]
- bzoj 2733: [HNOI2012]永无乡(线段树启发式合并)
- bzoj 2733: [HNOI2012]永无乡(线段树启发式合并)
- BZOJ 2733: [HNOI2012]永无乡(线段树启发式合并)
- 【BZOJ】【P2733】【HNOI2012】【永无乡】【题解】【启发式合并】
- BZOJ 2733 [HNOI2012] 永无乡 [线段树+并查集做法]
- Regular polygon HDU
- CNN 神经网络介绍
- Lua基础之table详解
- Java Iterator ListIterator 迭代器 以及 并发修改异常 ConcurrentModificationException
- Mac java环境变量配置过程记录
- [并查集+启发式合并]BZOJ 2733——[HNOI2012]永无乡
- Material design的学习笔记
- library not loaded 错误
- intent传递数据太大,报TransactionTooLargeException异常
- 在CentOS7中设置Tomcat开机自启动
- 关于unity3d for ARkit(一)
- java循环和switch混合简单应用
- 来听听资深设计师的想法(上)
- 关于C++的struct