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]永无乡的更多相关文章

  1. luoguP3224 [HNOI2012]永无乡【线段树,并查集】

    洞庭青草,近中秋,更无一点风色.玉鉴琼田三万顷,着我扁舟一叶.素月分辉,明河共影,表里俱澄澈.悠然心会,妙处难与君说. 应念岭表经年,孤光自照,肝胆皆冰雪.短发萧骚襟袖冷,稳泛沧溟空阔.尽挹西江,细斟 ...

  2. BZOJ 2733: [HNOI2012]永无乡 启发式合并treap

    2733: [HNOI2012]永无乡 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  3. bzoj 2733: [HNOI2012]永无乡 离线+主席树

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1167  Solved: 607[Submit][Status ...

  4. BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)

    不难...treap + 启发式合并 + 并查集 搞搞就行了 --------------------------------------------------------------------- ...

  5. BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]

    2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...

  6. B20J_2733_[HNOI2012]永无乡_权值线段树合并

    B20J_2733_[HNOI2012]永无乡_权值线段树合并 Description:n座岛,编号从1到n,每座岛都有自己的独一无二的重要度,按照重要度可以将这n座岛排名,名次用1到 n来表示.某些 ...

  7. 线段树合并+并查集 || BZOJ 2733: [HNOI2012]永无乡 || Luogu P3224 [HNOI2012]永无乡

    题面:P3224 [HNOI2012]永无乡 题解: 随便写写 代码: #include<cstdio> #include<cstring> #include<iostr ...

  8. bzoj2733: [HNOI2012]永无乡 启发式合并

    地址:http://www.lydsy.com/JudgeOnline/problem.php?id=2733 题目: 2733: [HNOI2012]永无乡 Time Limit: 10 Sec   ...

  9. [HNOI2012]永无乡 线段树合并

    [HNOI2012]永无乡 LG传送门 线段树合并练手题,写这篇博客只是为了给我的这篇文章找个板子题. 并查集维护连通性,对于不在同一个连通块内的合并操作每次直接合并两颗线段树,复杂度\(O(n \l ...

随机推荐

  1. swift(Object Storage对象存储服务)(单节点)

    # 在部署对象存储服务(swift)之前,你的环境必须包含身份验证服务(keystone); # keystone需要MySQL数据库,Rabbitmq服务,Memcached服务; # 内存:4G ...

  2. springboot成神之——Basic Auth应用

    本文介绍Basic Auth在spring中的应用 目录结构 依赖 入口DemoApplication 验证Authenication 配置WebSecurityConfig 控制器TestContr ...

  3. 19-EasyNetQ:用EasyNetQ.Hosepipe重新提交错误信息

    EasyNetQ.Hosepipe是EasyNetQ队列管理工具.用来取回队列中的消息并重新发布这些消息.还可以用它来检测错误队列,并重试发布消息. 用法 EasyNetQ.Hosepipe.exe ...

  4. 数据库与vs的连接

    新建一个MFC基于对话框的项目后,更改属性, 其中需要将include(里面都是MySQL的头文件)lib是库文件,将.dll放入与.exe同级目录下,或放入系统里(c:\windows\system ...

  5. saltstack系列(一)——介绍与安装

    saltstack简介 saltstack 是服务器基础架构集中化管理平台.具备配置管理.远程执行.监控等功能. saltstack 基于python. 注意: puppet是一种Linux.Unix ...

  6. Project2--Lucene的Ranking算法修改:BM25算法

    原文出自:http://blog.csdn.net/wbia2010lkl/article/details/6046661 1.       BM25算法 BM25是二元独立模型的扩展,其得分函数有很 ...

  7. 刷题向》图论》BZOJ1179 关于tarjan和SPFA的15秒(normal)

    这道题可以考察图论的掌握程度(算半道水题) 题目如下 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i ...

  8. Ubuntu 复制 拷贝和自适应屏幕

    ubuntu 16.04安装vmtools实测无效!!!!!!11 1.解决VMware workstation与主机的粘贴.复制.文件拖拽问题. 2.解决VMware workstations中Ub ...

  9. 第一次C语言作业:博客随笔

    1)你觉得大学和高中有什么差别?具体学习上哪? 大学自主学习较多,锻炼自己独立的品质.在学习上,增加了课程的深度和难度,由更多的活动. 2)我希望大学的师生关系是?阅读上述博客后对师生关系有何感想? ...

  10. 复习HTTP状态码+301和302

    一,HTTP状态码: 1xx:(信息状态码),接受的请求正在处理.2xx:(成功状态码),请求正常处理完毕.3xx:(重定向状态码),需要进行附加操作以完成请求.4xx:(客户端错误状态码),服务器无 ...