前置技能: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]森林的更多相关文章

  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 ...

随机推荐

  1. scikit-learning API

    API参考 这是scikit学习的类和函数参考.有关详细信息,请参阅完整的用户指南,因为类和功能原始规格可能不足以给出其使用的完整指导. sklearn.base:基类和效用函数 所有估计器的基类. ...

  2. BZOJ5484(LIS性质+树状数组)

    题目传送 学习的这篇题解. 结论: 1.直观感受一下会发现找到LIS,LIS里的东西相对位置是不会变的,其他的移一移总会排序成功的,所以其他的就是最小集合了,第一问的答案就是n-LIS: 2.寻找字典 ...

  3. 文件共享服务 FTP,NFS 和 Samba

    DAS DAS 指 Direct Attached Storage,即直连附加存储,这种设备直接连接到计算机主板总线上,计算机将其识别为一个块设备,例如常见的硬盘,U 盘等,这种设备很难做到共享. N ...

  4. 玩ztree的一段代码

    <!DOCTYPE HTML> <html lang="zh" xmlns:th="http://www.thymeleaf.org"> ...

  5. Java-注解(不包含元注解)

    @SuppressWarnings:抑制警告 package java.lang; import java.lang.annotation.*; import static java.lang.ann ...

  6. AJPFX关于StringBuffer,StringBuilder类 总结(一)

    StringBuffer,StringBuilder类 StringBuffer是同步的,数据安全,效率低;StringBuilder是不同步的,数据不安全,效率高 StringBuffer:概述1) ...

  7. AJPFX分享eclipse自动生成java注释方法

    设置方法介绍:eclipse中:Windows->Preferences->Java->Code Style->Code Template->Comments,然后对应的 ...

  8. 【学习笔记】深入理解js原型和闭包(11)——执行上下文栈

    继续上文的内容. 执行全局代码时,会产生一个执行上下文环境,每次调用函数都又会产生执行上下文环境.当函数调用完成时,这个上下文环境以及其中的数据都会被消除,再重新回到全局上下文环境.处于活动状态的执行 ...

  9. CMSIS的简介

    Cortex微控制器软件接口标准(Cortex Microcontroller Software Interface Standard)是ARM和一些编译器厂家以及半导体厂家共同遵循的一套标准,是由A ...

  10. PHP环境搭建Zend Studio 10.6.2+WampServer2.4

    址:http://www.zend.com/en/products/studio/downloads直接下载地址:http://downloads.zend.com/studio-eclipse/10 ...