[SDOI2013]森林 (启发式合并)
/*
树上主席树能够求出链上第k大, 然后启发式合并直接重构就好了
卡常数就卡呗
反正我就暴力重构了!!
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>
#define ll long long
#define mmp make_pair
#define M 100010
using namespace std;
int read() {
int nm = 0, f = 1;
char c = getchar();
for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
return nm * f;
}
int fa[M][17], sz[M], rt[M], belong[M], n, m, T, cnt, a[M], b[M], deep[M], ans;
int t[M * 17 * 17], ls[M * 17 * 17], rs[M * 17 * 17];
vector<int> to[M];
char s[M];
void modify(int l, int r, int last, int &now, int v) {
now = ++cnt;
t[now] = t[last] + 1;
ls[now] = ls[last];
rs[now] = rs[last];
if(l == r) return;
int mid = (l + r) >> 1;
if(v <= mid) modify(l, mid, ls[last], ls[now], v);
else modify(mid + 1, r, rs[last], rs[now], v);
}
void dfs(int now, int f, int zu) {
belong[now] = zu;
deep[now] = deep[f] + 1;
modify(1, n, rt[f], rt[now], a[now]);
fa[now][0] = f;
for(int i = 1; i <= 16; i++) fa[now][i] = fa[fa[now][i - 1]][i - 1];
for(int i = 0; i < to[now].size(); i++) {
int vj = to[now][i];
if(vj == f) continue;
dfs(vj, now, zu);
}
}
int lca(int a, int b) {
if(deep[a] < deep[b]) swap(a, b);
int dep = deep[a] - deep[b];
for(int i = 0; dep; i++, dep >>= 1) if(dep & 1) a = fa[a][i];
if(a == b) return a;
for(int i = 16; i >= 0; i--) {
if(fa[a][i] == fa[b][i]) continue;
a = fa[a][i], b = fa[b][i];
}
return fa[a][0];
}
int query(int l, int r, int rt1, int rt2, int rt3, int rt4, int k) {
if(l == r) return l;
int mid = (l + r) >> 1;
int v = t[ls[rt4]] + t[ls[rt3]] - t[ls[rt2]] - t[ls[rt1]];
if(k <= v) return query(l, mid, ls[rt1], ls[rt2], ls[rt3], ls[rt4], k);
else return query(mid + 1, r, rs[rt1], rs[rt2], rs[rt3], rs[rt4], k - v);
}
int main() {
read();
n = read(), m = read(), T = read();
for(int i = 1; i <= n; i++) a[i] = b[i] = read();
sort(b + 1, b + n + 1);
for(int i = 1; i <= n; i++) a[i] = lower_bound(b + 1, b + n + 1, a[i]) - b;
for(int i = 1; i <= m; i++) {
int vi = read(), vj = read();
to[vi].push_back(vj);
to[vj].push_back(vi);
}
for(int i = 1; i <= n; i++) {
if(!belong[i]) dfs(i, 0, i);
}
for(int i = 1; i <= n; i++) sz[belong[i]]++;
while(T--) {
scanf("%s", s + 1);
if(s[1] == 'Q') {
int vi = read() ^ ans, vj = read() ^ ans, k = read() ^ ans;
int l = lca(vi, vj);
ans = b[query(1, n, rt[l], rt[fa[l][0]], rt[vi], rt[vj], k)];
cout << ans << "\n";
} else {
int vi = read() ^ ans, vj = read() ^ ans;
if(sz[belong[vi]] > sz[belong[vj]]) swap(vi, vj);
sz[belong[vj]] += sz[belong[vi]];
sz[belong[vi]] = 0;
dfs(vi, vj, belong[vj]);
to[vi].push_back(vj);
to[vj].push_back(vi);
}
}
return 0;
}
/*
10
5 0 5
1 2 3 4 5
L 1 2
L 2 3
L 1 5
L 4 5
Q 3 4 1
*/
[SDOI2013]森林 (启发式合并)的更多相关文章
- BZOJ 3123 [SDOI2013] 森林 - 启发式合并 主席树
Description 给你一片森林, 支持两个操作: 查询$x$到$y$的$K$大值, 连接两棵树中的两个点 Solution 对每个节点$x$动态开权值线段树, 表示从$x$到根节点路径上权值出 ...
- BZOJ 3123: [Sdoi2013]森林 [主席树启发式合并]
3123: [Sdoi2013]森林 题意:一个森林,加边,询问路径上k小值.保证任意时刻是森林 LCT没法搞,树上kth肯定要用树上主席树 加边?启发式合并就好了,小的树dfs重建一下 注意 测试点 ...
- luoguP3302 [SDOI2013]森林 主席树 启发式合并
题目链接 luoguP3302 [SDOI2013]森林 题解 本来这题树上主席树暴力启发式合并就完了 结果把lca写错了... 以后再也不这么写了 复杂度\(O(nlog^2n)\) "f ...
- P3302 [SDOI2013]森林(主席树+启发式合并)
P3302 [SDOI2013]森林 主席树+启发式合并 (我以前的主席树板子是错的.......坑了我老久TAT) 第k小问题显然是主席树. 我们对每个点维护一棵包含其子树所有节点的主席树 询问(x ...
- [BZOJ3123][Sdoi2013]森林 主席树+启发式合并
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 第一行包含一个正整数testcase,表示当 ...
- BZOJ3123: [Sdoi2013]森林(启发式合并&主席树)
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4813 Solved: 1420[Submit][Status ...
- 【BZOJ3123】[Sdoi2013]森林 主席树+倍增LCA+启发式合并
[BZOJ3123][Sdoi2013]森林 Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整 ...
- BZOJ_3123_[Sdoi2013]森林_主席树+启发式合并
BZOJ_3123_[Sdoi2013]森林_主席树+启发式合并 Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20 ...
- [bzoj3123][Sdoi2013]森林_主席树_启发式合并
森林 bzoj-3123 Sdoi-2013 题目大意:给定一片共n个点的森林,T个操作,支持:连接两个不在一棵树上的两个点:查询一棵树上路径k小值. 注释:$1\le n,T \le 8\cdot ...
随机推荐
- 不使用循环或递归判断一个数是否为3的幂(leetcode 326)
326. Power of ThreeGiven an integer, write a function to determine if it is a power of three. Follow ...
- org.jsoup.Jsoup找不到jar包问题解决思路
今天在idea中导入项目,出现了这样的问题 通过idea的自带的导包功能,却提示找不到这个东西.于是就去maven仓库搜索这个咚咚 <!-- https://mvnrepository.com/ ...
- 实验五 CC2530平台上ADC组件的TinyOS编程
实验五 CC2530平台上ADC组件的TinyOS编程 实验目的: 加深和巩固学生对于TinyOS编程方法的理解和掌握 让学生初步掌握传感器的ADC组件应用方法 学生通过本实验能够初步的了解和掌握CC ...
- PX转REM简易计算器(适用于fittext.js插件计算)
当你使用fittext.js插件时,通过量取的像素单位PX计算出REM单位值,是一件比较麻烦而繁琐的,为了提高工作效率,自己闲暇写了个小DEMO,现在给大家分享出来. 先看dom: <heade ...
- linux 终端颜色代码
echo -e "\033[背景;字体颜色m 字符串\033[0m" eg : echo -e "\033[30m 黑色字 \033[0m" 字体颜色(30 ...
- JDBC-Oracle连接教程
前言 本文通过一个在Eclipse平台中搭建的小项目,在项目中使用一条静态命令来查询Oracle数据库测试用户“scott”下emp表中的几个字段,来学习JDBC连接数据库的方法.看完之后读者可以基本 ...
- Ansys热应力计算
目录 问题说明 温度场分析APDL 结果 问题说明 样块上下两端固定,在室温20℃下进行夹紧,分析其升温到150℃时的热应力. 采用间接法进行分析,温度场单元选择278,应力场单元为185 首先进行稳 ...
- 记SCOI2019
离精英体验营结束已两周的,要哭的要笑的现在也一定释怀了.是时候冷静分析一下这次的考试了.时间序虽然有流水账的嫌疑,但这毕竟是OI界的流行风气. day0 早上坐学校包的商务车去了电子科技大学.走在来过 ...
- ASP.NET: Cookie会话丢失,Session超时配置
问题描述: asp.net应用中web.config的SessionState节点:原先是 <sessionState mode="InProc" timeout=" ...
- QT中资源文件的使用
1.在工程中点右键,选添加文件: 在下一页中输入一个资源文件名,如uires,这样工程树下就会出现资源文件夹. 2.右键,选择“Open in Editor”打开它 3.添加或修改前缀名,前缀的作用类 ...