[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] ...
随机推荐
- 分布式集群下的Session存储方式窥探
传统的应用服务器,自身实现的session管理是大多是基于单机的,对于大型分布式网站来说,支撑其业务的远远不止一台服务器,而是一个分布式集群,请求在不同的服务器之间跳转.那么,如何保持服务器之前的se ...
- Apollo阿波罗配置中心docker
前言 在分布式系统中,要改个配置涉及到很多个系统,一个一个改效率低下,吃力不讨好.用配置中心可以解决这个问题.当然配置中心有不少,以下对比的表格是照搬Apollo Wiki的. 功能点 Apollo ...
- C语言_了解下结构体指针
在C语言中几乎可以创建指向任何类型的指针,包括用户自定义的类型.当然也可以指向结构体,先看一个小案例: #include <stdio.h> #include <string.h&g ...
- Mysql5.7在CentOs环境下定时备份数据库
咱创建一个目录,专门用于存放Mysql的备份文件./data/mysql_bak.写个shell脚本,每分钟备份一次测试以下. 脚本代码: chmod /testdir/backup.sh //给脚本 ...
- acdrem1083 人民城管爱人民 DP
思路:d(i, 0)表示从节点i到达大运村的最短路径,d(i, 1)表示从节点i到达大运村的次短路径. 1.最短路:当做DAG处理即可. 2.次短路:假设当前在u点处,下一个节点是v.v到终点的最短路 ...
- SpringBoot,Security4, redis共享session,分布式SESSION并发控制,同账号只能登录一次
由于集成了spring session ,redis 共享session,导致SpringSecurity单节点的session并发控制失效, springSession 号称 无缝整合httpses ...
- git 命令和使用场景总结
资料地址:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 http://w ...
- Spark第一个应用程序
首先要对源码进行编译,生成对应hadoop版本的spark开发程序jar包,上篇已经写了具体的过程,这里不再赘述. 在安装spark的机器上,下载eclipse-java-x86_64版本,将spar ...
- Python-ORM之sqlalchemy的简单使用
ORM之sqlalchemy 基础章节 使用SQLAlchemy链接数据库 from sqlalchemy import create_engine from sqlalchemy.ext.decla ...
- phpcmsv9更换模板介绍
先分享下大概的步骤: 1.上传模版文件到服务器:2.在站点管理 里边[模板风格配置]选择新模板:3.设置不同模型对应模板:4.修改现有的栏目,匹配新模板:5.更新栏目缓存.系统缓存,更新HTML静态页 ...