【洛谷 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 ...
随机推荐
- OpenFOAM——设置自定义非均匀场区域
在使用OpenFOAM进行计算的时候,我们需要对计算域设置非均匀场,比如最典型的溃坝算例,在开始计算以前,我们需要首先设定某一区域的水的体积分数为1,就是下面这样的: 有可能我们在计算传热问题的时候, ...
- 作业——12 hadoop大作业
作业的要求来自于:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3339 Hadoop综合大作业 1.以下是爬虫大作业产生的csv文件 ...
- 大数据应用期末总评(hadoop综合大作业)
作业要求源于:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/3363 一.将爬虫大作业产生的csv文件上传到HDFS (1)在/usr ...
- Redis系列 | Redis5.0 新特性
- nodejs 读取目前下所有文件
var fs = require('fs'); var join = require('path').join; function getJsonFiles(jsonPath) { let jsonF ...
- node 报错 env: node\r: No such file or directory
最近在编写一个命令行工具.使用 npm link 时可以正常运行.但是 ctrl+s 保存后, 再运行则报错 env: node\r: No such file or directory ,需要再 n ...
- Python的传递引用
在研究神经网络的反向传播的时候,不解一点,就是修改的是神经网络的paramets,为什么影响内部的神经元(层),比如Affine层:因为除了创建的时候,使用params作为Affine层的构造函数参数 ...
- LeetCode_443. String Compression
443. String Compression Easy Given an array of characters, compress it in-place. The length after co ...
- sigaction和实时信号sigqueue
sigaction函数sigaction函数的功能是用于改变进程接收到特定信号后的行为.int sigaction(int signum, const struct sigaction *act,st ...
- [简短问答]SET_PRINT_STYLEA相关简短问答
常见1:SET_PRINT_STYLEA(0,.....)放在那里参考官网下载中心的LODOP技术手册SET_PRINT_STYLEA篇,0代表前面紧跟着的打印项,放在需要该样式的打印项后面紧跟着. ...