点此看题面

大致题意: 给你一张图,其中每个点有一个权值,有两种操作:在两点之间连一条边,询问一个点所在联通块第\(k\)小的权值。

平衡树

看到第\(k\)小,应该不难想到平衡树

为了练习\(Splay\),所以我是用\(Splay\)来做这题的。

对于询问操作

对于询问操作,我们只要找到该节点所在\(Splay\)的根,然后查询第\(k\)小的权值即可,应该是\(Splay\)比较模板的操作吧。

因此就不多说了。

下面让我们来重点看一看连边操作。

对于连边操作

这才是真正恶心的操作。

考虑这条边连接的两个节点如果是在同一联通块,则完全不必考虑这条边。

但如果连接的是两个联通块,我们就需要合并这两个\(Splay\)。

至于如何合并,自然是启发式合并了。

而启发式合并的操作其实也非常简单,就是遍历较小的\(Splay\),然后把它里面的节点一个一个插入至较大的\(Splay\)中。

这样的时间复杂度看似极高,实际上均摊之后依然是可以接受的。

具体实现可以见代码。

代码

#include<bits/stdc++.h>
#define N 100000
#define M 300000
#define ull unsigned long long
#define swap(x,y) (x^=y^=x^=y)
using namespace std;
int n,m,a[N+5];
class FIO
{
private:
#define Fsize 100000
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,Fsize,stdin),A==B)?EOF:*A++)
#define pc(ch) (void)(FoutSize<Fsize?Fout[FoutSize++]=ch:(fwrite(Fout,1,FoutSize,stdout),Fout[(FoutSize=0)++]=ch))
int Top,FoutSize;char ch,*A,*B,Fin[Fsize],Fout[Fsize],Stack[Fsize];
public:
inline void read(int &x) {x=0;while(!isdigit(ch=tc()));while(x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));}
inline void read_alpha(char &x) {while(!isalpha(x=tc()));}
inline void writeln(int x) {if(!x) return pc('0'),pc('\n');if(x<0) pc('-'),x=-x;while(x) Stack[++Top]=x%10+48,x/=10;while(Top) pc(Stack[Top--]);pc('\n');}
inline void clear() {fwrite(Fout,1,FoutSize,stdout);}
}F;
class Class_splay//Splay模板
{
private:
#define PushUp(x) (node[x].Size=node[node[x].Son[0]].Size+node[node[x].Son[1]].Size+1)
#define Which(x) (node[node[x].Father].Son[1]==x)
#define Connect(x,y,d) (node[node[x].Father=y].Son[d]=x)
int rt,tot,data[N+5];
struct Tree
{
int Size,Father,Son[2];
inline void Clear() {Size=1,Father=Son[0]=Son[1]=0;}
}node[(N+M<<1)+5];
inline void Rotate(int x,int &k)
{
register int fa=node[x].Father,pa=node[fa].Father,d=Which(x);
(fa^k?node[pa].Son[Which(fa)]=x:k=x),node[x].Father=pa,Connect(node[x].Son[d^1],fa,d),Connect(fa,x,d^1),PushUp(fa),PushUp(x);
}
inline void Splay(int x,int &k) {for(register int fa=node[x].Father;x^k;Rotate(x,k),fa=node[x].Father) if(fa^k) Rotate(Which(x)^Which(fa)?x:fa,k);}
inline void Insert(int &x,int pos,int lst)
{
if(!x) return (void)(node[x=pos].Clear(),node[x].Father=lst);
Insert(node[x].Son[a[x]<a[pos]],pos,x),PushUp(x);
}
inline void dfs(int x,int rt)//遍历较小的Splay,将其节点一个个插入较大的Splay中
{
if(node[x].Son[0]) dfs(node[x].Son[0],rt);
if(node[x].Son[1]) dfs(node[x].Son[1],rt);
Insert(rt,x,0),Splay(x,rt);//插入
}
public:
inline void Init() {for(register int i=1;i<=n;++i) node[i].Size=1;}
inline void Union(int x,int y)//启发式合并x和y
{
while(node[x].Father) x=node[x].Father;//找到根节点
while(node[y].Father) y=node[y].Father;//找到根节点
if(!(x^y)) return;//如果在同一个联通块内就退出函数
if(node[x].Size<node[y].Size) swap(x,y);
dfs(y,x);
}
inline int get_val(int x,int rk)
{
while(node[x].Father) x=node[x].Father;
if(node[x].Size<rk) return -1;
while(x)
{
if(node[node[x].Son[0]].Size>=rk) x=node[x].Son[0];
else if(node[node[x].Son[0]].Size+1==rk) return x;
else rk-=node[node[x].Son[0]].Size+1,x=node[x].Son[1];
}
}
}splay;
int main()
{
register int i,Q,x,y;register char op;
for(F.read(n),F.read(m),i=1;i<=n;++i) F.read(a[i]);
for(splay.Init(),i=1;i<=m;++i) F.read(x),F.read(y),splay.Union(x,y);
for(F.read(Q);Q;--Q)
{
if(F.read_alpha(op),F.read(x),F.read(y),op^'Q') splay.Union(x,y);
else F.writeln(splay.get_val(x,y));
}
return F.clear(),0;
}

【BZOJ2733】[HNOI2012] 永无乡(启发式合并Splay)的更多相关文章

  1. bzoj2733: [HNOI2012]永无乡 启发式合并

    地址:http://www.lydsy.com/JudgeOnline/problem.php?id=2733 题目: 2733: [HNOI2012]永无乡 Time Limit: 10 Sec   ...

  2. BZOJ 2733: [HNOI2012]永无乡 启发式合并treap

    2733: [HNOI2012]永无乡 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

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

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

  4. bzoj2733: [HNOI2012]永无乡(splay)

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3778  Solved: 2020 Description 永 ...

  5. [Bzoj2733][Hnoi2012] 永无乡(BST)(Pb_ds tree)

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

  6. [BZOJ2733] [HNOI2012] 永无乡 (splay启发式合并)

    Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...

  7. BZOJ2733[HNOI2012]永无乡——线段树合并+并查集+启发式合并

    题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达 ...

  8. [bzoj2733][HNOI2012]永无乡_权值线段树_线段树合并

    永无乡 bzoj-2733 HNOI-2012 题目大意:题目链接. 注释:略. 想法: 它的查询操作非常友善,就是一个联通块内的$k$小值. 故此我们可以考虑每个联通块建一棵权值线段树. 这样的话每 ...

  9. BZOJ2733 [HNOI2012]永无乡 【线段树合并】

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

  10. bzoj2733: [HNOI2012]永无乡 线段树合并

    永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛. ...

随机推荐

  1. 【转载】Hyperledger学习小结

    Hyperledger学习小结 自学Hyperledger Composer也有段时间了,是时候对所学的知识总结一下了.因为没有实际项目参与的话,差不多也就到此为止了.后续可能会去了解一下以太坊的技术 ...

  2. 2017-10-6 清北刷题冲刺班a.m

    1.角谷猜想 #include<iostream> #include<cstdio> #include<cstring> #define maxn 10010 us ...

  3. 暴风魔镜SDK:MojingSDK For Unity V1.3.5112 (R).zip

    去年买了个暴风魔镜4,如今一直放在家里吃灰,这些天对Unity3D开发VR兴趣正浓,刚好公司项目不忙,花了几天玩玩暴风魔镜SDK,因为网上的资料不算多,暴风提供的文档也不太适合像我这样的Unity小白 ...

  4. 解决Maven项目中jar包依赖冲突问题

    版本冲突的解决方案 [1]调节原则 [1]路径最短者优先原则 [2]路径相同时,先声明者优先原则 [2]排除原则:用于排除某项依赖的依赖jar包 <dependency> <grou ...

  5. Linq to xml 读取xml文件或xml字符串

    XMLFile1.xml: XDocument Contacts = XDocument.Load("XMLFile1.xml"); //XElement Contacts = X ...

  6. thinkphp5加密解密

    thinkphp5目前没有提供加密解密类,但是tp3.2中提供了好几种加密解密方法,我们可以吧3.2的这些类拿来使用. 1.将tp3.2中ThinkPHP\Library\Think的Crypt文件夹 ...

  7. (转)centos7.4 fdisk磁盘分区 格式化 挂载

    centos7.4 fdisk磁盘分区 格式化 挂载 原文:http://blog.csdn.net/capecape/article/details/78499351 1.查看系统中有多少可以识别的 ...

  8. SpringBoot | 第七章:过滤器、监听器、拦截器

    前言 在实际开发过程中,经常会碰见一些比如系统启动初始化信息.统计在线人数.在线用户数.过滤敏高词汇.访问权限控制(URL级别)等业务需求.这些对于业务来说一般上是无关的,业务方是无需关系的,业务只需 ...

  9. ASP编码规范

    ASP编码规范(--::) 第一章 ASP编码规范通述 ASP编码分为两大部分,一部分为静态文件编码,一部分为包含服务器端脚本的动态文件编码. 静态文件编码分script编码和HTML编码两部分. 服 ...

  10. java网络访问指定出口ip

    java网络访问指定出口ip Table of Contents 1. socket 2. apache httpclient 1 socket 可以在Socket构造函数中指定使用的本地ip,如: ...