前置技能: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. Codeforces Round #302 (Div. 1) 训练

    链接: http://codeforces.com/contest/543 过程: 惨淡的只做出了A和C 题解: A 题解: 简单的一道题 我们用$dp[i][j]$表示当前考虑到前num个人(这个另 ...

  2. 洛谷p1115 最大子段和

    题目链接: 最大子段和 题目分析: 动态规划O(n)求解,设f[i]表示以i为终点的最大子段和 分两种情况: 若f[i-1]>0,则显然f[i]=f[i-1]+a[i](a[i]必须包含在内) ...

  3. 题解报告:hdu 6441 Find Integer(费马大定理+智慧数)

    Problem Description people in USSS love math very much, and there is a famous math problem .give you ...

  4. 转 ORACLE数据库ORA-00392 log 4 of thread 1 is being cleared, operation not allowed错误

    现象: 数据库在做to-time recovery, 时候,restore and recover 都是正常的,但是最后一步open resetlogs 报错如下 ORA-00392 原因: 因为是在 ...

  5. (022)[工具软件]图片浏览 JPEGView

    JPEGView是一款小巧绿色快速的图像浏览工具,并且支持全屏或窗口模式.主页地址: https://sourceforge.net/projects/jpegview/JPEGView软件小巧,但功 ...

  6. session共享方法

    session数据保存在memcached,redis这种内存数据库内 memcache比较简单,使用的场景比较多.redis支持的数据类型多.而且数据具有期限,和session和期限可以配合使用 通 ...

  7. C#的WinForm中Label透明一例

    很久之前開發的一個MIS系統,里面有個登錄界面,採用了PictureBox做背景,上面放了一些Label,試了很多方面不能實現透明,如下圖: 這次重新啟用該系統,看了一下原因,很簡單,原來Label的 ...

  8. AJPFX总结string类和简单问题

    String表示字符串,所谓字符串,就是一连串的字符;String是不可变类,一旦String对象被创建,包含在对象中的字符序列(内容)是不可变的,直到对象被销毁://一个String对象的内容不能变 ...

  9. 【学习笔记】OSG 基本几何图元

    例:geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); 来指定要利用这些数据生成一个怎么样的形状. ...

  10. 一键修改android 字体和图片大小.

    项目中需要动态更改 app的字体和图片, 在查阅中找到的更改主题的解决办法,和单独的修改字体的方法.  这两种方法的确有效果但是实现麻烦,在修改字体的过程中,找到一个额外的方法,  修改字体的实现更改 ...