luoguP3224 [HNOI2012]永无乡
https://www.luogu.org/problemnew/show/P3224
考虑对每个岛维护一颗平衡树,用并查集维护连通性,启发式合并即可
这东西其实是一个大暴力,每次把节点少的平衡树合并到节点多的平衡树里
这样可以保证每个点合并一次树的大小*2,每个点最多被插入 log(n) 次,复杂度正确
我使用了简单好写的 leafy tree 作为平衡树,不喜勿喷
#include <bits/stdc++.h>
#define update(u) if(u -> left -> size) u -> size = u -> left -> size + u -> right -> size, u -> value = u -> right -> value
#define new_Node(a, b, c, d) (&(*st[cnt++] = Node(a, b, c, d)))
#define merge(a, b) new_Node(a -> size + b -> size, b -> value, a, b)
#define ratio 4
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
template <typename _T>
inline void read(_T &f) {
f = 0; _T fu = 1; char c = getchar();
while(c < '0' || c > '9') {if(c == '-') fu = -1; c = getchar();}
while(c >= '0' && c <= '9') {f = (f << 3) + (f << 1) + (c & 15); c = getchar();}
f *= fu;
}
const int N = 300000 + 10;
struct Node {
int size, value;
Node *left, *right;
Node (int a, int b, Node *c, Node *d) : size(a), value(b), left(c), right(d) {}
Node () {}
}*root[N], *st[N], t[N], *null;
int w[N], v[N], f[N], pre[N], len;
int n, m, q, cnt = 0;
void maintain(Node *u) {
if(u -> left -> size > u -> right -> size * ratio) u -> right = merge(u -> left -> right, u -> right), st[--cnt] = u -> left, u -> left = u -> left -> left;
if(u -> right -> size > u -> left -> size * ratio) u -> left = merge(u -> left, u -> right -> left), st[--cnt] = u -> right, u -> right = u -> right -> right;
}
void ins(Node *u, int x) {
if(u -> size == 1) u -> left = new_Node(1, min(u -> value, x), null, null), u -> right = new_Node(1, max(u -> value, x), null, null);
else ins(x > u -> left -> value ? u -> right : u -> left, x);
update(u); maintain(u);
}
int find(Node *u, int x) {
if(u -> size == 1) return u -> value;
return x > u -> left -> size ? find(u -> right, x - u -> left -> size) : find(u -> left, x);
}
void dfs(Node *u) {
if(u == null) return;
st[--cnt] = u;
dfs(u -> left);
if(u -> size == 1) w[++len] = u -> value;
dfs(u -> right);
}
int Merge(int a, int b) {
if(root[a] -> size < root[b] -> size) swap(a, b);
len = 0; dfs(root[b]);
for(register int i = 1; i < len; i++) {
ins(root[a], w[i]);
}
return a;
}
int find(int x) {
return f[x] == x ? x : f[x] = find(f[x]);
}
int main() {
read(n); read(m);
null = new Node(0, 0, 0, 0);
for(register int i = 0; i <= 300000; i++) st[i] = &t[i];
for(register int i = 1; i <= n; i++) root[i] = new Node(1, INT_MAX, null, null), read(v[i]), ins(root[i], v[i]), f[i] = i, pre[v[i]] = i;
for(register int i = 1; i <= m; i++) {
int a, b;
read(a); read(b);
int x = find(a), y = find(b);
if(x == y) continue;
int fa = Merge(x, y);
f[x] = f[y] = fa;
}
read(q);
for(register int i = 1; i <= q; i++) {
char c = getchar();
while(c != 'Q' && c != 'B') c = getchar();
if(c == 'Q') {
int a, b;
read(a); read(b);
int x = find(a);
if(root[x] -> size - 1 < b) {
printf("-1\n");
continue;
}
printf("%d\n", pre[find(root[x], b)]);
} else {
int a, b;
read(a); read(b);
int x = find(a), y = find(b);
if(x == y) continue;
int fa = Merge(x, y);
f[x] = f[y] = fa;
}
}
return 0;
}
luoguP3224 [HNOI2012]永无乡的更多相关文章
- luoguP3224 [HNOI2012]永无乡【线段树,并查集】
洞庭青草,近中秋,更无一点风色.玉鉴琼田三万顷,着我扁舟一叶.素月分辉,明河共影,表里俱澄澈.悠然心会,妙处难与君说. 应念岭表经年,孤光自照,肝胆皆冰雪.短发萧骚襟袖冷,稳泛沧溟空阔.尽挹西江,细斟 ...
- BZOJ 2733: [HNOI2012]永无乡 启发式合并treap
2733: [HNOI2012]永无乡 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- bzoj 2733: [HNOI2012]永无乡 离线+主席树
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1167 Solved: 607[Submit][Status ...
- BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)
不难...treap + 启发式合并 + 并查集 搞搞就行了 --------------------------------------------------------------------- ...
- BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]
2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...
- B20J_2733_[HNOI2012]永无乡_权值线段树合并
B20J_2733_[HNOI2012]永无乡_权值线段树合并 Description:n座岛,编号从1到n,每座岛都有自己的独一无二的重要度,按照重要度可以将这n座岛排名,名次用1到 n来表示.某些 ...
- 线段树合并+并查集 || BZOJ 2733: [HNOI2012]永无乡 || Luogu P3224 [HNOI2012]永无乡
题面:P3224 [HNOI2012]永无乡 题解: 随便写写 代码: #include<cstdio> #include<cstring> #include<iostr ...
- bzoj2733: [HNOI2012]永无乡 启发式合并
地址:http://www.lydsy.com/JudgeOnline/problem.php?id=2733 题目: 2733: [HNOI2012]永无乡 Time Limit: 10 Sec ...
- [HNOI2012]永无乡 线段树合并
[HNOI2012]永无乡 LG传送门 线段树合并练手题,写这篇博客只是为了给我的这篇文章找个板子题. 并查集维护连通性,对于不在同一个连通块内的合并操作每次直接合并两颗线段树,复杂度\(O(n \l ...
随机推荐
- 实用webpack-dev-server
webpack-dev-server的作用 文件作出改动之后,保存,立即开始编译文件 编译后的文件是保存在内存中的,在项目文件夹中看不到编译后的文件 编译完成之后立即自动刷新浏览器 测试webpack ...
- Python中特殊函数和表达式 filter,map,reduce,lambda
1. filter 官方解释:filter(function or None, sequence) -> list, tuple, or string Return those items of ...
- leetcode427
本题不会做,从网上找到了python3的解法,记录如下. class Solution: def construct(self, grid): def dfs(x, y, l): if l == 1: ...
- Stars(树状数组单点更新)
Astronomers often examine star maps where stars are represented by points on a plane and each star h ...
- sonarLint 插件配置sonarQube Server
Connected Mode You can bind Eclipse projects to a SonarQube project (supporting SonarQube servers 5. ...
- 编译错误error: invalid&nbsp…
昨天遇到一个莫名其妙的编译错误,以前没有见过,而且代码流程看起来也没有太多的奇异之处.后来忍无可忍,百度了下,发现别人也有遇到这个错误的,他的解决方法是:少了"}". 嘿嘿,我开始 ...
- spring 项目返回406
406 The resource identified by this request is only capable of generating responses with characteris ...
- springBoot集成 quartz动态定时任务
项目中需要用到定时任务,考虑了下java方面定时任务无非就三种: 用Java自带的timer类.稍微看了一下,可以实现大部分的指定频率的任务的调度(timer.schedule()),也可以实现关闭和 ...
- Docker学习笔记_安装和使用Redis
一.准备 1.宿主机OS:Win10 64位 2.虚拟机OS:Ubuntu18.04 3.操作账号:Docker 二.安装过程 1.搜索Redis su ...
- 面试题:servlet jsp cook session 背1
一.Servlet是什么?JSP是什么?它们的联系与区别是什么? Servlet是Java编写的运行在Servlet容器的服务端程序,狭义的Servlet是指Servlet接口,广义的Servlet是 ...