「BZOJ 2733」「HNOI 2012」永无乡「启发式合并」
题意
你需要维护若干连通快,有两个操作
- 合并\(x,y\)所在的连通块
- 询问\(x\)所在连通块中权值从小到大排第\(k\)的结点编号
题解
可以启发式合并\(splay\),感觉比较好些的
一个连通块就是一个\(splay\),每次合并挑小的\(splay\)遍历一遍把点按中序遍历存下来,然后一个一个插入大的\(splay\)就行了;查询就是\(splay\)的\(kth\)操作
这样时间复杂度\(O(n \log n)\),它的证明可以见2018论文集 :董炜隽《浅谈Splay与Treap的性质及其应用》,其中有提一个\(\text{Dynamic Finger Theorem}\)
(其实随便插入的话是两个\(\log\),也能通过,十分玄学)
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
const int N = 2e5 + 10;
int n, m, q, bel[N], rt[N], w[N];
int ch[N][2], fa[N], sz[N];
void upd(int u) { sz[u] = sz[ch[u][0]] + sz[ch[u][1]] + 1; }
int dir(int u) { return ch[fa[u]][1] == u; }
void rotate(int u) {
int d = dir(u), f = fa[u];
if(fa[u] = fa[f]) ch[fa[u]][dir(f)] = u;
if(ch[f][d] = ch[u][d ^ 1]) fa[ch[f][d]] = f;
fa[ch[u][d ^ 1] = f] = u;
upd(f); upd(u);
}
void ins(int &rt, int u, int f = 0) {
if(!rt) {
rt = u; fa[u] = f; sz[u] = 1;
ch[u][0] = ch[u][1] = 0;
return ;
}
ins(ch[rt][w[u] > w[rt]], u, rt);
upd(rt);
}
void splay(int u) {
for(; fa[u]; rotate(u)) if(fa[fa[u]])
rotate(dir(u) == dir(fa[u]) ? fa[u] : u);
rt[bel[u]] = u;
}
int kth(int u, int k) {
int v = u;
while(1) {
if(k <= sz[ch[v][0]]) v = ch[v][0];
else {
k -= sz[ch[v][0]] + 1;
if(k <= 0) break ;
v = ch[v][1];
}
}
splay(v);
return v;
}
int a[N], l;
void dfs(int u) {
if(u) {
dfs(ch[u][0]);
a[++ l] = u;
dfs(ch[u][1]);
}
}
void link(int u, int v) {
u = bel[u]; v = bel[v];
if(u == v) return ;
if(sz[rt[u]] < sz[rt[v]]) swap(u, v);
l = 0; dfs(rt[v]);
for(int i = 1; i <= l; i ++) {
bel[a[i]] = u;
ins(rt[u], a[i]);
splay(a[i]);
}
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++) scanf("%d", w + i);
for(int i = 1; i <= n; i ++) {
bel[i] = rt[i] = i; sz[i] = 1;
}
int u, v;
for(int i = 1; i <= m; i ++) {
scanf("%d%d", &u, &v);
link(u, v);
}
scanf("%d", &q);
char op[5];
for(int i = 1; i <= q; i ++) {
scanf("%s%d%d", op, &u, &v);
if(* op == 'Q') {
u = rt[bel[u]];
if(v > sz[u]) puts("-1");
else printf("%d\n", kth(u, v));
}
if(* op == 'B') link(u, v);
}
return 0;
}
「BZOJ 2733」「HNOI 2012」永无乡「启发式合并」的更多相关文章
- 【BZOJ 2733】【HNOI 2012】永无乡 Splay启发式合并
启发式合并而已啦,, 调试时发现的错误点:insert后没有splay,把要拆开的树的点插入另一个树时没有把ch[2]和fa设为null,找第k大时没有先减k,,, 都是常犯的错误,比赛时再这么粗心就 ...
- BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)
不难...treap + 启发式合并 + 并查集 搞搞就行了 --------------------------------------------------------------------- ...
- BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]
2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...
- BZOJ 2733 [HNOI2012]永无乡(启发式合并+Treap+并查集)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2733 [题目大意] 给出n个点,每个点都有自己的重要度,现在有连边操作和查询操作, 查 ...
- ☆ [HNOI2012] 永无乡 「平衡树启发式合并」
题目类型:平衡树启发式合并 传送门:>Here< 题意:节点可以连边(不能断边),询问任意两个节点的连通性与一个连通块中排名第\(k\)的节点 解题思路 如果不需要询问排名,那么并查集即可 ...
- bzoj 2733 : [HNOI2012]永无乡 (线段树合并)
Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...
- 2733: [HNOI2012]永无乡 线段树合并
题目: https://www.lydsy.com/JudgeOnline/problem.php?id=2733 题解: 建n棵动态开点的权值线段树,然后边用并查集维护连通性,边合并线段树维护第k重 ...
- bzoj 2733 永无乡 - 并查集 - 线段树
永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛. ...
- BZOJ 2733: [HNOI2012]永无乡 启发式合并treap
2733: [HNOI2012]永无乡 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
随机推荐
- windows环境下,安装zookeeper~
1. 概述 ZooKeeper是Hadoop的正式子项目,它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护.名字服务.分布式同步.组服务等.ZooKeeper的目标就是封装好复杂 ...
- MFC学习(一) MFC基础类及其层次结构
从类CCmdTarget派生出绝大多数MFC中的类,其层次结构如下图: 从根类Cobject层层派生出绝大多数MFC中的类,层次结构如下图: MFC中重点类: CObject类是MFC的绝大部分类的基 ...
- mybatis 学习一 建立maven项目
一.直接建立Maven项目方法 1.建立Maven项目 接下来使用Eclipse的maven构建一个web项目,以构建SpringMVC项目为例: 1.1 选择建立Maven Project 选择Fi ...
- 内网渗透神器xerosploit
项目地址:https://github.com/LionSec/xerosploit 安装完成后直接在终端输入xerosploit打开 显示了本机的内网ip,mac地址,网关,网卡,输入help查看帮 ...
- HTTP协议头域详解
HTTP协议头域详解 Requests部分 Accept 指定客户端能够接收的内容类型 Accept: text/plain, text/html Accept-Charset 浏览器可以接受的字符编 ...
- 使用Java进行远程方法调用的几个方案及比较
Java远程方法调用是编程过程中比较常见的问题,列举一下主要包括如下几类: 1.Java RMI (Remote Method Invocation) 2.EJB远程接口调用 3.WebService ...
- 02-26 ASP.NET加密解密的方法
MD5加密.解密的方法. 使用时的代码备忘:Response.Write(FormsAuthentication.HashPasswordForStoringInConfigFile("要加 ...
- Delphi Help
http://docwiki.embarcadero.com/CodeExamples/Seattle/en/Category:Content_by_Version
- S3C6410的启动代码分析 一
本文开始第一篇,启动代码的编写,注意,仅仅是启动代码,并不是bootloader,因为只有boot,没有loader. 第一要明确:CPU上电之后,会从某个固定地址执行指令.ARM结构的CPU从地址0 ...
- 修改Tomcat可支持get传参方式的url长度,get形式
maxHttpHeaderSize="8192"加在 <Connector port="8081" maxHttpHeaderSize="314 ...