[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 ...
随机推荐
- eclipse启动tomcat错误解决
clipse启动tomcat报出下面的错误提示: 控制台: 九月 06, 2018 9:01:31 下午 org.apache.tomcat.util.digester.SetPropertiesRu ...
- 2018.11.25 AMC-ICPC 亚洲区域赛(焦作站)吊银
11月23日 大清早,跟着wyb的脚步,早起跑过去听方伟的编译原理,然鹅一点都没听进去,在焦作胡辣汤群里疯狂灌水... 听说焦作那边冷得不行,前一天看天气预报说那边已经是2℃了,都快零下了,然鹅学校里 ...
- tab切换 原生js
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 20164322韩玉婷 -----EXP3 免杀原理与实践
基础问题回答 1.杀软是如何检测出恶意代码的? (1)基于特征码的检测 特征码是能识别一个程序是一个病毒的一段不大于64字节的特征串.如果一个可执行文件包含这样的特征码则被杀毒软件检测为是恶意代码. ...
- SQA计划
一.SQA计划 1.软件工程 所做程序是一个长沙大学的学习app系统 .可以实现用户的注册登录,课程学习,以及活动参加.根据需求建模,进行体系结构设计,然后设计. 2.质量保证 (1)项目需要符合IE ...
- python 编写登陆接口
#!/usr/bin/env python#_*_ coding:utf-8 _*_dic={ 'yts':{'password':'123','count':0}, 'nick':{'passwor ...
- wpf 圆角TextBox 样式
<Style x:Key="RoundCornerTextStyle" TargetType="{x:Type TextBox}"> <Set ...
- webpack 配置别名,解决 import 时路径查找麻烦的问题
在编写代码时,使用 import 导入别的文件,可能会遇到查找路径麻烦的问题 比如这里的 ../../ 还要去思考多少个 ../ 那么可以在 webpack 中,将 src 目录设置一个别名,方便文件 ...
- Android 异步请求通用类
package com.example.demo1; import java.util.EventListener; public interface MyAsyncTaskListener exte ...
- C++ 属性类
又一次向目标迈进了... 这次是实现一个物体所拥有的属性类.没什么好说的,非常简单. 因为我是C++新手,不知道对这次的实现有没有什么更好的实现方式.因为这个类对以后的进展很重要,而且,要充分考虑易用 ...