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 ...
随机推荐
- dd命令的解释
dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 注意:指定数字的地方若以下列字符结尾,则乘以相应的数字:b=512:c=1:k=1024:w=2 参数注释: 1. if=文件名:输入 ...
- GridView导出成Excel字符"0"丢失/数字丢失的处理方式 收藏
GridView导出成Excel字符"0"丢失/数字丢失的处理方式 收藏 GridView 导出成Excel文件,这个代码在网上比较多.但是发现存在一个问题,导出的数据中如果有&q ...
- AngularJS学习(二)——Angular应用的解析
本节描述AngularJS应用程序的三个组成部分,并解释它们如何映射到模型-视图-控制器设计模式 模板(Template) 模板是您用HTML和CSS编写的文件,展现应用的视图.您可给HTML添加新的 ...
- Centos手动编译安装vim8
系统:CentOs6.9 gcc版本:5.1.0 github上拉取vim工程之后,cd src,执行一下命令: $ ./configure $ sudo make gcc -c -I. -Iprot ...
- 用户“*****”不具有所需的权限。请验证授予了足够的权限并且解决了 Windows 用户帐户控制(UAC)限制问题。
错误: 用户“ts\***”不具有所需的权限.请验证授予了足够的权限并且解决了 Windows 用户帐户控制(UAC)限制问题. 解决: 当从客户端用IE连接http://xxx.xxx.xxx.xx ...
- Python和其他语言的区别 (简单精辟啊 手打)
首先是简单 读和写非常容易 免费 免费且开源 社区为专业人士和初学者提供知识和经验的分享交流平台 兼容性 与多平台兼容 面向对象 支持面向对象编程 php面向网络 函数库 python 社区创建了丰富 ...
- 238. Product of Array Except Self 由非己元素形成的数组
[抄题]: Given an array of n integers where n > 1, nums, return an array output such that output[i] ...
- BT下载的原理 和疑问
我心中有几个疑问,同时也搜索了点素材,肯能对理解问题有帮助. BT下载,即P2P下载,是一种不需要中心化服务器的下载,实现原理是,每个客户端在下载的时候也作为服务器. 我的疑问是,P2P各个节点是如何 ...
- Apache fcgistarter命令
一.简介 fcgistarter命令用于启动FastCGI程序. 二.语法 fcgistarter -c command -p port [ -i interface ] -N num 参考:http ...
- django: rest-framework的 分页和过滤
django: rest-framework的 分页和过滤 2018年06月28日 10:09:01 weixin_42359464 阅读数:136 标签: flaskrestframeworkdja ...