题意:给定一个带点权的无向图,有两种操作:

  1、将两个连通分量合并。

  2、查询某个连通分量里的第K大点。

题解:

用并查集维护连通关系,一开始建立n棵splay树,然后不断合并,查询。

处理技巧:

  1、每个顶点u所在的Splay就是T[find(u)]。

  2、每个顶点在树中对应的节点编号就是该顶点的编号。

 #include <cstdio>
#include <iostream>
#define maxn 100110
using namespace std; int key[maxn], pre[maxn], son[maxn][], siz[maxn], ntot;
struct Splay {
int root;
Splay():root(){}
void update( int nd ) {
siz[nd] = siz[son[nd][]] + siz[son[nd][]] + ;
}
void rotate( int nd, int d ) {
int p = pre[nd];
int s = son[nd][!d];
int ss = son[s][d]; son[nd][!d] = ss;
son[s][d] = nd;
if( p ) son[p][ nd==son[p][] ] = s;
else root = s; pre[nd] = s;
pre[s] = p;
if( ss ) pre[ss] = nd; update( nd );
update( s );
}
void splay( int nd, int top= ) {
while( pre[nd]!=top ) {
int p = pre[nd];
int nl = nd==son[p][];
if( pre[p]==top ) {
rotate( p, nl );
} else {
int pp = pre[p];
int pl = p==son[pp][];
if( nl==pl ) {
rotate( pp, pl );
rotate( p, nl );
} else {
rotate( p, nl );
rotate( pp, pl );
}
}
}
}
int initnode( int nd, int k, int p ) {
key[nd] = k;
pre[nd] = p;
son[nd][] = son[nd][] = ;
siz[nd] = ;
return nd;
}
void insert( int k, int nnd ) {
if( !root ) {
root = initnode(nnd,k,);
return;
}
int nd = root;
while( son[nd][ k>key[nd] ] )
nd = son[nd][ k>key[nd] ];
son[nd][ k>key[nd] ] = initnode(nnd,k,nd);
update( nd );
splay( nd );
}
int nth( int n ) {
int nd = root;
while( ) {
int ls = siz[son[nd][]];
if( n<=ls ) {
nd = son[nd][];
} else if( n>=ls+ ) {
nd = son[nd][];
n -= ls+;
} else {
break;
}
}
splay(nd);
return nd;
}
inline int size() { return siz[root]; }
static void join( Splay &T , int snd ) {
if( !snd ) return;
join( T, son[snd][] );
join( T, son[snd][] );
T.insert( key[snd], snd );
}
}; int n, m, q;
int fa[maxn];
Splay T[maxn]; int find( int a ) {
return a==fa[a] ? a : fa[a]=find(fa[a]);
} void join( int a, int b ) {
if( find(a)==find(b) ) return;
if( T[find(a)].size() > T[find(b)].size() ) swap(a,b);
Splay::join( T[find(b)], T[find(a)].root );
fa[find(a)] = find(b);
} int main() {
scanf( "%d%d", &n, &m );
for( int i=,w; i<=n; i++ ) {
scanf( "%d", &w );
fa[i] = i;
T[i].insert( w, i );
}
for( int i=,u,v; i<=m; i++ ) {
scanf( "%d%d", &u, &v );
join(u,v);
}
scanf( "%d", &q );
while( q-- ) {
char ch[];
int a, b;
scanf( "%s%d%d", ch, &a, &b );
if( ch[]=='B' ) {
join(a,b);
} else {
if( !(<=b&&b<=T[find(a)].size()) ) printf( "-1\n" );
else printf( "%d\n", T[find(a)].nth(b) );
}
}
}

bzoj 2733 Splay 启发式合并,名次树的更多相关文章

  1. bzoj2733: [HNOI2012]永无乡(splay+启发式合并/线段树合并)

    这题之前写过线段树合并,今天复习Splay的时候想起这题,打算写一次Splay+启发式合并. 好爽!!! 写了长长的代码(其实也不长),只凭着下午的一点记忆(没背板子...),调了好久好久,过了样例, ...

  2. BZOJ 2733 & splay的合并

    题意: 带权联通块,添边与查询联通块中第k大. SOL: splay合并+并查集. 我以为splay可以用奇技淫巧来简单合并...调了一下午终于幡然醒悟...于是就只好一个一个慢慢插...什么启发式合 ...

  3. bzoj 2733 平衡树启发式合并

    首先对于一个连通块中,询问我们可以直接用平衡树来求出排名,那么我们可以用并查集来维护各个块中的连通情况,对于合并两个平衡树,我们可以暴力的将size小的平衡树中的所有节点删掉,然后加入大的平衡树中,因 ...

  4. BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]

    2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...

  5. BZOJ 2733 [HNOI2012]永无乡 - 启发式合并主席树

    Description 1: 查询一个集合内的K大值 2: 合并两个集合 Solution 启发式合并主席树板子 Code #include<cstdio> #include<cst ...

  6. 【BZOJ2733】永无乡[HNOI2012](splay启发式合并or线段树合并)

    题目大意:给你一些点,修改是在在两个点之间连一条无向边,查询时求某个点能走到的点中重要度第k大的点.题目中给定的是每个节点的排名,所以实际上是求第k小:题目求的是编号,不是重要度的排名.我一开始差点被 ...

  7. bzoj 3674: 可持久化并查集加强版 (启发式合并+主席树)

    Description Description:自从zkysb出了可持久化并查集后……hzwer:乱写能AC,暴力踩标程KuribohG:我不路径压缩就过了!ndsf:暴力就可以轻松虐!zky:…… ...

  8. 【BZOJ-2733】永无乡 Splay+启发式合并

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2048  Solved: 1078[Submit][Statu ...

  9. BZOJ2733 永无乡【splay启发式合并】

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

随机推荐

  1. 如何实用便捷的在本地真机调试WEB端HTML5网页

    先简单介绍两款常用但需要一定条件或限制的工具 1.如果你能FQ chrome在32版本后就自带了移动端调度工具,可以在Android直接联调,但唯一遗憾的是,在我大天朝要FQ后才能行的通,我自己试了后 ...

  2. Fiddler 断点调试http请求

    fiddler有两种断点,Before Requests(可以修改请求参数).After Responses(可以修改返回值) Before Requests 断点 1.设置Before Reques ...

  3. nginx 配置代理某个路径

    location /test{ proxy_pass http://localhost:8765/test; proxy_set_header Host $http_host; } 其中红色的那句可以 ...

  4. count(*)与count(1)、count('xxx')等在使用语法方面的区别

    语法方面: 区别就是:没有区别!!! “*”号是通配符: “*”号是通配符 “*”号是通配符 使用"*"号和使用其他数字和任意非字段字符在使用方面没有任何语法错误; 至于效率方面是 ...

  5. 用js实现登录的简单验证

    实现过程示意图 代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...

  6. spring源码解析--事务篇(前篇)

    对于每一个JAVA程序员,spring应该是再熟悉不过的框架了,它的功能有多强大我就不多说了,既然他有这么强大的功能,是如何实现的呢?这个就需要从他的原理去了解,而最直接了解原理的方式莫过于源码.当然 ...

  7. [BZOJ3150][Ctsc2013]猴子 期望dp+高斯消元

    3150: [Ctsc2013]猴子 Time Limit: 20 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 163  Solved: 10 ...

  8. python collections模块详解

    参考老顽童博客,他写的很详细,例子也很容易操作和理解. 1.模块简介 collections包含了一些特殊的容器,针对Python内置的容器,例如list.dict.set和tuple,提供了另一种选 ...

  9. ServiceWorker pwa缓存

    index.js if ( navigator.serviceWorker ) { console.log("cache index") window.addEventListen ...

  10. css 画的动画表情

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...