【洛谷 P3224】 [HNOI2012]永无乡(Splay,启发式合并)
题目链接
启发式合并就是暴力合并把小的合并到大的里,一个一个插进去。
并查集维护连通性,同时保证并查集的根就是所在Splay的根,这样能省去很多操作。
#include <cstdio>
#include <algorithm>
using namespace std;
inline int read(){
int s = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-')w = -1;ch = getchar();}
while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0',ch = getchar();
return s * w;
}
const int MAXN = 100010;
struct SplayTree{
int ch[2], fa, val, size;
}t[MAXN];
int num, root, n, m, f[MAXN];
int find(int x){
return f[x] == x ? x : f[x] = find(f[x]);
}
void pushup(int u){
t[u].size = t[t[u].ch[0]].size + t[t[u].ch[1]].size + 1;
}
void rotate(int x){
int y = t[x].fa;
int z = t[y].fa;
int k = t[y].ch[1] == x;
t[z].ch[t[z].ch[1] == y] = x;
t[x].fa = z;
t[y].ch[k] = t[x].ch[k ^ 1];
t[t[x].ch[k ^ 1]].fa = y;
t[x].ch[k ^ 1] = y;
t[y].fa = x;
pushup(y);
pushup(x);
}
void Splay(int x, int goal){
while(t[x].fa){
int y = t[x].fa, z = t[y].fa;
if(z)
/**/ (t[z].ch[0] == y) ^ (t[y].ch[0] == x) ? rotate(x) : rotate(y);
rotate(x);
}
if(goal == 0) root = x;
}
inline int findKth(int k){
int u = root;
while(1){
if(t[t[u].ch[0]].size >= k) u = t[u].ch[0];
else if(t[t[u].ch[0]].size == k - 1) return u;
else k -= t[t[u].ch[0]].size + 1, u = t[u].ch[1];
}
}
int next(int x, int mode){
int u = t[x].ch[mode];
while(t[u].ch[!mode]) u = t[u].ch[!mode];
return u;
}
int a, b;
char c;
void insert(int x){
int u = root, fa = 0;
while(u) fa = u, u = t[u].ch[t[x].val > t[u].val];
t[fa].ch[t[x].val > t[fa].val] = x;
t[x].fa = fa;
Splay(x, 1);
}
void merge(int u){
if(t[u].ch[0]) merge(t[u].ch[0]);
if(t[u].ch[1]) merge(t[u].ch[1]);
t[u].ch[0] = t[u].ch[1] = 0; insert(u);
}
int T;
int main(){
n = read(); m = read();
for(int i = 1; i <= n; ++i)
t[i].val = read(), t[i].size = 1, f[i] = i;
for(int i = 1; i <= m; ++i){
a = read(); b = read();
int x = find(a), y = find(b);
if(x == y) continue;
if(t[x].size > t[y].size){
f[y] = x;
root = x; merge(y); Splay(x, 0);
}
else{
f[x] = y;
root = y; merge(x); Splay(y, 0);
}
}
T = read();
for(int i = 1; i <= T; ++i){
c = getchar(); while(c != 'Q' && c != 'B') c = getchar();
a = read(); b = read();
if(c == 'B'){
int x = find(a), y = find(b);
if(x == y) continue;
if(t[x].size > t[y].size){
f[y] = x;
root = x; merge(y); Splay(x, 0);
}
else{
f[x] = y;
root = y; merge(x); Splay(y, 0);
}
}
else{
root = find(a);
if(t[root].size < b) printf("%d\n", -1);
else printf("%d\n", findKth(b));
}
}
return 0;
}
【洛谷 P3224】 [HNOI2012]永无乡(Splay,启发式合并)的更多相关文章
- 洛谷.3224.[HNOI2012]永无乡(Splay启发式合并)
题目链接 查找排名为k的数用平衡树 合并时用启发式合并,把size小的树上的所有节点插入到size大的树中,每个节点最多需要O(logn)时间 并查集维护连通关系即可 O(nlogn*insert t ...
- 洛谷P3224 [HNOI2012]永无乡(线段树合并+并查集)
题目描述 永无乡包含 nnn 座岛,编号从 111 到 nnn ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 nnn 座岛排名,名次用 111 到 nnn 来表示.某些岛之间由巨大的桥连接, ...
- 洛谷 P3224 [HNOI2012]永无乡 解题报告
P3224 [HNOI2012]永无乡 题目描述 永无乡包含 \(n\) 座岛,编号从 \(1\) 到 \(n\) ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 \(n\) 座岛排名,名次用 ...
- BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]
2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...
- 洛谷 P3224 [HNOI2012]永无乡
题面 永无乡包含 \(n\) 座岛,编号从 \(1\) 到 \(n\) ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 \(n\) 座岛排名,名次用 \(1\) 到 \(n\) 来表示.某些岛 ...
- [BZOJ2733] [HNOI2012] 永无乡 (splay启发式合并)
Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...
- 【洛谷3224/BZOJ2733】[HNOI2012]永无乡 (Splay启发式合并)
题目: 洛谷3224 分析: 这题一看\(n\leq100000\)的范围就知道可以暴力地用\(O(nlogn)\)数据结构乱搞啊-- 每个联通块建一棵Splay树,查询就是Splay查询第k大的模板 ...
- [洛谷P3224][HNOI2012]永无乡
题目大意:给你$n$个点,每个点有权值$k$,现有两种操作: 1. $B\;x\;y:$将$x,y$所在联通块合并2. $Q\;x\;k:$查询第$x$个点所在联通块权值第$k$小是哪个数 题解:线段 ...
- 2018.08.11 洛谷P3224 [HNOI2012]永无乡(线段树合并)
传送门 给出n个带点权的点,支持连边和查询连通块第k大. 这个貌似就是一道线段树合并的裸板啊... 代码: #include<bits/stdc++.h> #define N 100005 ...
- 【BZOJ-2733】永无乡 Splay+启发式合并
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2048 Solved: 1078[Submit][Statu ...
随机推荐
- IT 常用单词表
程序员英语单词册 前言 程序员必备的600个英语词汇(1) 程序员必备的600个英语词汇(2) 程序员必备的600个英语词汇(3) 程序员必备的600个英语词汇(4) 程序员不 ...
- 刷题记录:[CISCN2019 总决赛 Day2 Web1]Easyweb
目录 刷题记录:[CISCN2019 总决赛 Day2 Web1]Easyweb 一.涉及知识点 1.敏感文件泄露 2.绕过及sql注入 3.文件上传:短标签绕过php过滤 刷题记录:[CISCN20 ...
- Win10电脑桌面壁纸自动变成黑色无法更换怎么解决
很多用户在升级到win10之后,发现在使用过程中经常会碰到一些问题,就是电脑桌面壁纸总是会自动变成黑色,而且无法设置桌面背景壁纸,这是怎么回事呢,出现这样的问题可能是因为系统不是正版,或者是电脑设置不 ...
- vs2015 编译obs studio 遇到的几个错误
1. >D:\project\vs\obs\ObsProject\obs-studio\plugins\win-wasapi\win-wasapi.cpp(245): error C2065: ...
- mysql查询、子查询、连接查询
mysql查询.子查询.连接查询 一.mysql查询的五种子句 where子句(条件查询):按照“条件表达式”指定的条件进行查询. group by子句(分组):按照“属性名”指定的字段进行分组.gr ...
- Spring的异步方法
先把longTimeMethod 封装到Spring的异步方法中,这个异步方法的返回值是Future的实例.这个方法一定要写在Spring管理的类中,注意注解@Async. @Service publ ...
- 错误详情:已取消该操作。--------- 在 System.Threading.CancellationToken.ThrowOperationCanceledException()
错误详情:已取消该操作.--------- 在 System.Threading.CancellationToken.ThrowOperationCanceledException() 在 Syste ...
- 廖雪峰Git教程3
转自:https://www.liaoxuefeng.com/wiki/896043488029600 [标签管理] 发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签 ...
- Python高级笔记(十)闭包
1. 闭包 #!/usr/bin/python # -*- encoding=utf- -*- def test(number): # 在函数里面再定义一个函数,并且这个函数用到外边函数的变量,那么将 ...
- 判断命令test
判断命令test一般用于脚本当中,可以简写为中括号[ ].其会对跟随的条件进行判断,一般可以分为数值判断.字符串判断和文件判断.语法格式为test [判断条件]或[ 判断条件 ],注意中括号[ ]与判 ...