[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] ...
随机推荐
- maven的下载安装,配置本地仓库
maven的下载安装 下载地址:http://maven.apache.org/download.cgi 下载完成后解压到某一个目录 配置环境变量 第一个环境变量 MAVEN_HOME A:\mave ...
- Jenkins代码管理
1.1 Jenkins安装与下载应用代码 应用部署 http://jenkins-ci.org http://wordpress.org/ http://core.svn.wordp ...
- python入门学习笔记(一)
写在开头: A:python的交互式环境 ...
- mac 上格式化磁盘出现MediaKit报告设备上的空间不足以执行请求的解决办法
1.问题描述: 我使用是一个2T移动硬盘,分了5个区 2.分析原因:因为mac OSX的日志式格式需要有EFI分区进行引导,而我的移动硬盘是没有EFI分区的,这样的话就会出现问题: 3.解决办法: 1 ...
- django-高级视图和url配置
高级视图和url配置 一.URLconf技巧 1.流线型化函数导入 对于配置url,我们可以使用以下几种方式: (1)引入view中的函数 from firstSite.view import cur ...
- 判断json是否包含了每个键 PHP
(1)可以用array_key_exists去判断object对象或array数组中是否含有某个键: (2)不可以用isset去判断判断object对象或array数组中是否含有某个键 $decode ...
- Appium安卓真机环境搭建
说明 步骤可能比较简洁,因为手头上有安卓测试机,所以需要配置虚拟机的童鞋请去虫师博客园,因为我也是从那儿学的,哈哈.点我飞到虫师那儿 但是如果你要搭建真机测试环境的话,本教程将是最简单实用的. 1. ...
- c#获取文件MD5算法
//获取文件MD5算法 private static string GetMD5FromFile(string fileName) { try { FileStream file = new File ...
- ubuntu 14.04 分辨率调整 -- xrandr命令
问题描述: 自己在安装ubuntu-kylin 14.04 TLS系统成功后,在调整分辨率的时候(系统设置--显示)发现分辨率的选项只有1024x768以及800x600两个选项,而台式机的外接显示屏 ...
- windowsXP下搭建JAVA环境教程
一.工具准备安装JKD6:传送门:http://www.java.net/download/jdk6/6u10/promoted/b32/binaries/jdk-6u10-rc2-bin-b32-w ...