luogu3302 [SDOI2013]森林
前置技能:Count on a tree
然后带上一个启发式合并
#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;
int n, m, orz, uu, vv, ww, a[80005], b[80005], rnk[80005], rem, cnt, tt[15];
int hea[80005], fa[80005], siz[80005], gra[80005][19], qaq, lst;
int rot[80005], lson[9000005], rson[9000005], sum[9000005], dep[80005];
bool vis[80005];
char ss[15];
struct Edge{
int too, nxt;
}edge[320005];
void add_edge(int fro, int too){
edge[++cnt].nxt = hea[fro];
edge[cnt].too = too;
hea[fro] = cnt;
}
int insert(int pre, int l, int r, int x){
int rt=++qaq;
int mid=(l+r)>>1;
lson[rt] = lson[pre]; rson[rt] = rson[pre]; sum[rt] = sum[pre] + 1;
if(l==r) return rt;
if(x<=mid) lson[rt] = insert(lson[pre], l, mid, x);
if(mid<x) rson[rt] = insert(rson[pre], mid+1, r, x);
return rt;
}
void dfs(int o, int f, int r){
fa[o] = f;
siz[r]++;
dep[o] = dep[f] + 1;
vis[o] = true;
gra[o][0] = f;
for(int i=1; i<=16; i++)
gra[o][i] = gra[gra[o][i-1]][i-1];
rot[o] = insert(rot[f], 1, rem, rnk[o]);
for(int i=hea[o]; i; i=edge[i].nxt){
int t=edge[i].too;
if(t!=f) dfs(t, o, r);
}
}
int build(int l, int r){
int rt=++qaq;
int mid=(l+r)>>1;
if(l==r) return rt;
if(l<=mid) lson[rt] = build(l, mid);
if(mid<r) rson[rt] = build(mid+1, r);
return rt;
}
int getLca(int uu, int vv){
if(dep[uu]<dep[vv]) swap(uu, vv);
for(int i=16; i>=0; i--)
if(dep[gra[uu][i]]>=dep[vv])
uu = gra[uu][i];
if(uu==vv) return uu;
for(int i=16; i>=0; i--)
if(gra[uu][i]!=gra[vv][i]){
uu = gra[uu][i];
vv = gra[vv][i];
}
return gra[uu][0];
}
int query(int l, int r, int k){
int tmp=0;
tmp -= sum[lson[tt[1]]] + sum[lson[tt[2]]];
tmp += sum[lson[tt[3]]] + sum[lson[tt[4]]];
if(l==r) return l;
int mid=(l+r)>>1;
if(k<=tmp){
for(int i=1; i<=4; i++)
tt[i] = lson[tt[i]];
return query(l, mid, k);
}
else{
for(int i=1; i<=4; i++)
tt[i] = rson[tt[i]];
return query(mid+1, r, k-tmp);
}
}
int myfind(int x){
return x==fa[x]?x:fa[x]=myfind(fa[x]);
}
int main(){
cin>>n;
cin>>n>>m>>orz;
for(int i=1; i<=n; i++){
scanf("%d", &a[i]);
b[i] = a[i];
fa[i] = i;
}
sort(b+1, b+1+n);
rem = unique(b+1, b+1+n) - (b + 1);
for(int i=1; i<=n; i++){
int tmp=lower_bound(b+1, b+1+rem, a[i])-b;
rnk[i] = tmp;
}
for(int i=1; i<=m; i++){
scanf("%d %d", &uu, &vv);
add_edge(uu, vv);
add_edge(vv, uu);
}
rot[0] = build(1, rem);
for(int i=1; i<=n; i++)
if(!vis[i])
dfs(i, 0, i), fa[i]=i;
while(orz--){
scanf("%s", ss);
if(ss[0]=='Q'){
scanf("%d %d %d", &uu, &vv, &ww);
uu ^= lst; vv ^= lst; ww ^= lst;
int lca=getLca(uu, vv);
tt[1] = rot[lca]; tt[2] = rot[gra[lca][0]];
tt[3] = rot[uu]; tt[4] = rot[vv];
lst = b[query(1, rem, ww)];
printf("%d\n", lst);
}
else{
scanf("%d %d", &uu, &vv);
uu ^= lst; vv ^= lst;
int r1=myfind(uu);
int r2=myfind(vv);
if(siz[r1]<siz[r2]) swap(uu, vv), swap(r1, r2);
add_edge(uu, vv);
add_edge(vv, uu);
dfs(vv, uu, r1);
}
}
return 0;
}
luogu3302 [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 ...
随机推荐
- AtCoder Regular Contest 062 E - AtCoDeerくんと立方体づくり / Building Cubes with AtCoDeer
题目传送门:https://arc062.contest.atcoder.jp/tasks/arc062_c 题目大意: 给你\(N\)块正方形木板,每块木板四角有四种颜色(可以相同),木板中央有编号 ...
- 【模板】RMQ问题的ST表实现
$RMQ$问题:给定一个长度为$N$的区间,$M$个询问,每次询问$[L_i,R_i]$这段区间元素的最大值/最小值. $RMQ$的高级写法一般有两种,即为线段树和$ST$表. 本文主要讲解一下$ST ...
- IIR型高斯滤波的原理及实现
二.实现 GIMP中有IIR型高斯滤波的实现,代码位于contrast-retinex.c中,读者可自行查看.下面给出本人实现的核心代码: #include"stdafx.h" t ...
- 74LVC2G241双缓冲3态驱动器
- LVS集群-DR模式
同上个实验一样,还是准备三台机器 分发器(sishen_63):eth0 192.168.1.63 RealServer1sishen_64) RealServer2sishen_65) 首先配置网卡 ...
- Sqlserver调用WebApi
原文地址 http://www.cnblogs.com/lflyq/p/6065160.html sp_configure 'show advanced options', 1;GORECONFI ...
- AJPFX总结heap和stack有什么区别?
栈是后进先出的线性表结构,存取速度比堆快.创建对象的时候new一个对象,引用存在栈上具体的内容存在堆上. 栈与堆都是Java用来在RAM中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不 ...
- position 位置、表单
一.position 位置 1.只要使用了定位,必须有一个相对的参照物 2.具体定位的那个元素需加position:absolute:(绝对的) 绝对的:就是具体到某一个地方,特别详细的意思 ...
- android java 知识点
ublic,protected,friendly,private的访问权限如下: 关键字 当前类 同一package 子孙类 其他package p ...
- jacob的使用方法
网上一大堆你抄我的,我抄你的,但基本配置都没说清,做个笔记让后来的人少走冤枉路 1.下载最新的jacob,jdk版本一一对应,1.6对应jacob的1.16,1.7对应1.17.... 2.应用程序将 ...