/*
树上主席树能够求出链上第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]森林 (启发式合并)的更多相关文章

  1. BZOJ 3123 [SDOI2013] 森林 - 启发式合并 主席树

    Description 给你一片森林, 支持两个操作: 查询$x$到$y$的$K$大值,  连接两棵树中的两个点 Solution 对每个节点$x$动态开权值线段树, 表示从$x$到根节点路径上权值出 ...

  2. BZOJ 3123: [Sdoi2013]森林 [主席树启发式合并]

    3123: [Sdoi2013]森林 题意:一个森林,加边,询问路径上k小值.保证任意时刻是森林 LCT没法搞,树上kth肯定要用树上主席树 加边?启发式合并就好了,小的树dfs重建一下 注意 测试点 ...

  3. luoguP3302 [SDOI2013]森林 主席树 启发式合并

    题目链接 luoguP3302 [SDOI2013]森林 题解 本来这题树上主席树暴力启发式合并就完了 结果把lca写错了... 以后再也不这么写了 复杂度\(O(nlog^2n)\) "f ...

  4. P3302 [SDOI2013]森林(主席树+启发式合并)

    P3302 [SDOI2013]森林 主席树+启发式合并 (我以前的主席树板子是错的.......坑了我老久TAT) 第k小问题显然是主席树. 我们对每个点维护一棵包含其子树所有节点的主席树 询问(x ...

  5. [BZOJ3123][Sdoi2013]森林 主席树+启发式合并

    3123: [Sdoi2013]森林 Time Limit: 20 Sec  Memory Limit: 512 MB Description Input 第一行包含一个正整数testcase,表示当 ...

  6. BZOJ3123: [Sdoi2013]森林(启发式合并&主席树)

    3123: [Sdoi2013]森林 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 4813  Solved: 1420[Submit][Status ...

  7. 【BZOJ3123】[Sdoi2013]森林 主席树+倍增LCA+启发式合并

    [BZOJ3123][Sdoi2013]森林 Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整 ...

  8. BZOJ_3123_[Sdoi2013]森林_主席树+启发式合并

    BZOJ_3123_[Sdoi2013]森林_主席树+启发式合并 Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20 ...

  9. [bzoj3123][Sdoi2013]森林_主席树_启发式合并

    森林 bzoj-3123 Sdoi-2013 题目大意:给定一片共n个点的森林,T个操作,支持:连接两个不在一棵树上的两个点:查询一棵树上路径k小值. 注释:$1\le n,T \le 8\cdot ...

随机推荐

  1. flask 数据库迁移的简单操作

    1.目的:修改现有数据库的表结构,不改变数据库中现有的数据. 2.导包:from flask_migrate import Migrate, MigrateCommandfrom flask_scri ...

  2. Mybatis集成Oracle

    首先需要导入Oracle的驱动,这部分会有一个天坑 Maven无法直接将我们所需的Oracle驱动加入项目中,手动加入依赖也是无效(原因还在分析),而且驱动无效如果不注意的话是看不出来的,他不会在编译 ...

  3. MATLAB实现Brovey图像融合

    自定义函数: function BF=Brovey_fuse(Hyperspectral_image,High_resolution_image) x0=imread(Hyperspectral_im ...

  4. vue修改框架样式/deep/

    /deep/ 父元素的样式名 /deep/ 要修改的样式名 使用 ... 貌似不行

  5. 一个简单springboot搭建

    首先,新建一个maven项目,new maven project 然后打开pom.xml,引入需要的jar包,代码如下: <parent> <groupId>org.sprin ...

  6. 理解 if __name__ == '__main__'

    简单地理解Python中的if __name__ == '__main__' if __name__ == '__main__'的意思是: 当.py文件被直接运行时,if __name__ == '_ ...

  7. 对TSNU网站的初步分析

    这是一个教育网的网站,其中网站的教务子系统,html页面是用表单嵌套来格式化显示样式的,另外还有<div>.<iframe>等等 .在这个上有个form表单,提交的参数有如下几 ...

  8. Linux第六节课学习笔记

    if条件测试语句可以让脚本根据实际情况自动执行相应的命令,可以分为单分支.双分支与多分支. /dev/null为无回收功能的垃圾箱. read是用来读取用户输入信息的命令,-p用来显示提示信息. fo ...

  9. MySQL 表字段操作

    MySQL 表字段操作 一.增加表字段 1)mysql> alter table 二.删除表字段 三.修改表字段

  10. jQuery实现的3个基础案例(仿QQ列表分组,二级联动下拉框,模拟员工信息管理系统)

    1.仿QQ列表分组 <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type&quo ...