主席树
离散化后
每个点储存从根到它的路径上的点权
新加边时直接用启发式合并,直接把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]森林的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. 洛谷 P3302 [SDOI2013]森林 解题报告

    P3302 [SDOI2013]森林 题目描述 小\(Z\)有一片森林,含有\(N\)个节点,每个节点上都有一个非负整数作为权值.初始的时候,森林中有\(M\)条边. 小Z希望执行\(T\)个操作,操 ...

  8. 3123: [Sdoi2013]森林

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

  9. bzoj 3123: [Sdoi2013]森林(45分暴力)

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

  10. AC日记——[Sdoi2013]森林 bzoj 3123

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

随机推荐

  1. [Python Study Notes]字符串处理技巧(持续更新)

    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ...

  2. dig挖出DNS的秘密

    [最简单的dig用法] 最简单的dig用法,当然就是直接输入dig按回车. 1 2 3 4 5 6 $ dig   ; <<>> DiG 9.8.2rc1-RedHat-9.8 ...

  3. MySQL事务处理案例演示

    <?php $mysqli=new mysqli("localhost", "root", "123456", "xsphp ...

  4. Zabbix 3.2.4至3.2.7的升级方案

    1.关闭Zabbix Server 防止有新的数据提交到数据库中,也可以关闭数据库.如果更新过程中,评估告警信息可以忽略,可以先执行备份操作. 1.1.检查当前版本 /usr/local/zabbix ...

  5. Java经典编程题50道之四十二

    809*??=800*??+9*??+1,其中??代表的两位数,8*??的结果为两位数,9*??的结果为3位数.求??代表的两位数,以及809*??后的结果. public class Example ...

  6. Java经典编程题50道之十一

    有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? public class Example11 { public static void main(String[] arg ...

  7. C#委托与事件--简单笔记

    委托 简单记录点东西 适合似懂非懂的朋友看看 委托类型用来定义和响应应用程序中的回调. 借此可以设计各种有面向对象特性的代码模式.下面要说的事件在我看来就是委托的一种实现,再深一步讲,利用委托加事件, ...

  8. Spring-Security 自定义Filter完成验证码校验

    Spring-Security的功能主要是由一堆Filter构成过滤器链来实现,每个Filter都会完成自己的一部分工作.我今天要做的是对UsernamePasswordAuthenticationF ...

  9. Elasticsearch教程-从入门到精通(转载)

    转载,原文地址:http://mageedu.blog.51cto.com/4265610/1714522?utm_source=tuicool&utm_medium=referral 各位运 ...

  10. ContentProvider、ContentResolver、ContentObserver之间的关系

    ContentProvider.ContentResolver.ContentObserver之间的关系 ContentPRrovider: * 四大组件的内容提供者,主要用于对外提供数据 * 实现各 ...