[SDOI2013]森林
主席树
离散化后
每个点储存从根到它的路径上的点权
新加边时直接用启发式合并,直接把size小的重构
询问时sum[u]+sum[v]-sum[lca]-sum[fa[lca]]来比较,在树上二分
LCA用倍增求,在启发式合并时暴力更新
连通性用并查集维护,再维护每个联通快的size
空间开大点就可以过了
# include <bits/stdc++.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int _(2e5 + 10), __(1e7 + 10);
IL ll Read(){
RG char c = getchar(); RG ll x = 0, z = 1;
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
}
int n, m, len, w[_], fst[_], nxt[_], to[_], cnt, deep[_], id[_], fa[17][_], ls[__], rs[__], sz[__], rt[__], num, Fa[_], size[_];
IL void Add(RG int u, RG int v){ to[cnt] = v; nxt[cnt] = fst[u]; fst[u] = cnt++; }
IL void Build(RG int &x, RG int l, RG int r){
x = ++num; if(l == r) return;
RG int mid = (l + r) >> 1;
Build(ls[x], l, mid); Build(rs[x], mid + 1, r);
}
IL void Modify(RG int &x, RG int l, RG int r, RG int val){
sz[++num] = sz[x]; ls[num] = ls[x]; rs[num] = rs[x];
sz[x = num]++;
if(l == r) return;
RG int mid = (l + r) >> 1;
if(val <= mid) Modify(ls[x], l, mid, val);
else Modify(rs[x], mid + 1, r, val);
}
IL int Query(RG int A, RG int B, RG int C, RG int D, RG int l, RG int r, RG int k){
if(l == r) return l;
RG int sum = sz[ls[A]] + sz[ls[B]] - sz[ls[C]] - sz[ls[D]], mid = (l + r) >> 1;
if(sum >= k) return Query(ls[A], ls[B], ls[C], ls[D], l, mid, k);
else return Query(rs[A], rs[B], rs[C], rs[D], mid + 1, r, k - sum);
}
IL void Dfs(RG int u, RG int Fa){
deep[u] = deep[Fa] + 1; fa[0][u] = Fa;
for(RG int j = 1; j <= 16; j++) fa[j][u] = fa[j - 1][fa[j - 1][u]];
rt[u] = rt[Fa]; Modify(rt[u], 1, len, id[u]);
for(RG int e = fst[u]; e != -1; e = nxt[e]) if(to[e] != Fa) Dfs(to[e], u);
}
IL int LCA(RG int x, RG int y){
if(deep[x] < deep[y]) swap(x, y);
for(RG int j = 16; j >= 0; j--) if(deep[fa[j][x]] >= deep[y]) x = fa[j][x];
if(x == y) return x;
for(RG int j = 16; j >= 0; j--) if(fa[j][x] != fa[j][y]) x = fa[j][x], y = fa[j][y];
return fa[0][x];
}
IL int Find(RG int x){ return Fa[x] == x ? x : Fa[x] = Find(Fa[x]); }
int main(RG int argc, RG char* argv[]){
Read(); n = Read(); m = Read(); RG int T = Read(), ans = 0, x, y, k; num = cnt = 0;
for(RG int i = 1; i <= n; i++) id[i] = w[i] = Read(), Fa[i] = i, size[i] = 1, fst[i] = -1;
sort(w + 1, w + n + 1); len = unique(w + 1, w + n + 1) - w - 1;
for(RG int i = 1; i <= n; i++) id[i] = lower_bound(w + 1, w + len + 1, id[i]) - w;
for(RG int i = 1, u, v; i <= m; i++){
u = Read(), v = Read(), Add(u, v), Add(v, u);
RG int fx = Find(u), fy = Find(v);
Fa[fx] = fy; size[fy] += size[fx];
}
Build(rt[0], 1, len);
for(RG int i = 1; i <= n; i++) if(!deep[i]) Dfs(i, 0);
while(T--){
RG char c; scanf(" %c", &c);
x = Read() ^ ans; y = Read() ^ ans;
if(c == 'L'){
RG int fx = Find(x), fy = Find(y);
if(size[fx] < size[fy]) swap(x, y);
Dfs(y, x);
Fa[fx] = fy; size[fy] += size[fx];
Add(x, y); Add(y, x);
}
else{
k = Read() ^ ans; RG int lca = LCA(x, y);
ans = w[Query(rt[x], rt[y], rt[lca], rt[fa[0][lca]], 1, len, k)];
printf("%d\n", ans);
}
}
return 0;
}
[SDOI2013]森林的更多相关文章
- 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. 第二行包含三个整 ...
- 洛谷 P3302 [SDOI2013]森林 解题报告
P3302 [SDOI2013]森林 题目描述 小\(Z\)有一片森林,含有\(N\)个节点,每个节点上都有一个非负整数作为权值.初始的时候,森林中有\(M\)条边. 小Z希望执行\(T\)个操作,操 ...
- 3123: [Sdoi2013]森林
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 3336 Solved: 978[Submit][Status] ...
- bzoj 3123: [Sdoi2013]森林(45分暴力)
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4184 Solved: 1235[Submit][Status ...
- AC日记——[Sdoi2013]森林 bzoj 3123
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 3216 Solved: 944[Submit][Status] ...
随机推荐
- 如何在Centos 7上用Logrotate管理日志文件
何为Logrotate? Logrotate是一个实用的日志管理工具,旨在简化对系统上生成大量的日志文件进行管理. Logrotate允许自动旋转压缩,删除和邮寄日志文件,从而节省宝贵的磁盘空间. L ...
- httping:测量网站延迟
遇到网络问题的时候,我们一般会先通过 ping 这个工具来了解基本的情况.httping 与 ping 类似,不过它不是发送 ICMP 请求,而是发送 HTTP 请求.利用 httping,我们可以测 ...
- windows FileZilla Server 开启FTP over TLS
FileZilla Server官方下载地址: https://filezilla-project.org/download.php?type=server FileZilla Server 开启FT ...
- 通过云主机(网关机)远程登录内网mysql
国内的一些云主机平台(UCloud,阿里云,腾讯云等)走的都是网关机+内网机(即局域网)模式,网关机代理外网访问,不能直接连接内网机器.本文介绍通过远程登录云主机,并设置本地代理的方式,通过sqlyo ...
- 一个例子理解break和continue的区别
结论:break用于终止整个循环,而continue用于终止某一次循环.public class Test { public static void main(String[] args) { for ...
- Shiro 核心功能案例讲解 基于SpringBoot 有源码
Shiro 核心功能案例讲解 基于SpringBoot 有源码 从实战中学习Shiro的用法.本章使用SpringBoot快速搭建项目.整合SiteMesh框架布局页面.整合Shiro框架实现用身份认 ...
- RHEL6误安装RHEL7的包导致glibc被升级后系统崩溃处理方法
RHEL6误使用了RHEL7的光盘源,安装了某个RPM包之后,导致glibc被升级,进而导致系统崩溃. [root@rhel65 ~]# yum install ftp Loaded plugin ...
- SharedPreferences封装类
最近一直在读马伟奇老师的简书,给人以不一样的感觉,接下来的时间会做做笔记,毕竟好东西变成自己的才有用 原文地址SharedPreferencesUtils 依赖 dependencies { comp ...
- Codeforces348C - Subset Sums
Portal Description 给出长度为\(n(n\leq10^5)\)的序列\(\{a_n\}\)以及\(m(m\leq10^5)\)个下标集合\(\{S_m\}(\sum|S_i|\leq ...
- Xmind8 Pro安装教程 Windows
xmind是一款优秀的思维导图制作软件,这一点相信不用太多解释. 尤其作为测试人员导出测试用例为excel极其方便.网上xmind的破解方法加自己琢磨,重新整理了破解步骤. 亲测可以永久激活截止2 ...