[Sdoi2013]森林(启发式合并+主席树)
对于操作1,显然可以使用主席树维护,然后对于一条链(x,y),假设lca为f,根为rt,则(rt,x)+(rt,y)-(rt,f)-(rt,fa[f])即为所求的链,在主席树上直接查询即可,查询方式类似于treap/splay对size的询问。
对于操作2,可以用LCT,当然也能启发式合并,每次连边时,强行把sz小的塞入sz大的即可。
#include<bits/stdc++.h>
using namespace std;
const int N=;
int n,m,p,a[N],b[N],rt[N],sz[N],fa[N],dep[N],f[N][];
vector<int>G[N];
namespace tree{
struct seg{int lc,rc,s;}tr[N*];
int sz;
void update(int k,int l,int r,int&rt,int prt)
{
tr[rt=++sz]=tr[prt],tr[rt].s++;
if(l==r)return;
int mid=l+r>>;
if(k<=mid)update(k,l,mid,tr[rt].lc,tr[prt].lc);
else update(k,mid+,r,tr[rt].rc,tr[prt].rc);
}
int query(int u,int v,int pu,int pv,int k,int l,int r)
{
if(l==r)return l;
int mid=l+r>>,sum=tr[tr[u].lc].s+tr[tr[v].lc].s-tr[tr[pu].lc].s-tr[tr[pv].lc].s;
if(k<=sum)return query(tr[u].lc,tr[v].lc,tr[pu].lc,tr[pv].lc,k,l,mid);
return query(tr[u].rc,tr[v].rc,tr[pu].rc,tr[pv].rc,k-sum,mid+,r);
}
}
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void dfs(int u,int Fa,int anc)
{
f[u][]=Fa;
for(int i=;i<=;i++)f[u][i]=f[f[u][i-]][i-];
sz[anc]++,dep[u]=dep[Fa]+,fa[u]=Fa;
int x=lower_bound(b+,b+p+,a[u])-b;
tree::update(x,,p,rt[u],rt[Fa]);
for(int i=;i<G[u].size();i++)if(G[u][i]!=Fa)dfs(G[u][i],u,anc);
}
int lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
int t=dep[x]-dep[y];
for(int i=;(<<i)<=t;i++)if(t&(<<i))x=f[x][i];
if(x==y)return x;
for(int i=;~i;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
return f[x][];
}
int main()
{
int Q;scanf("%*d%d%d%d",&n,&m,&Q);
for(int i=;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i],fa[i]=i;
for(int i=,x,y;i<=m
;i++)scanf("%d%d",&x,&y),G[x].push_back(y),G[y].push_back(x);
sort(b+,b+n+);
p=unique(b+,b+n+)-b-;
for(int i=;i<=n;i++)if(!dep[i])dfs(i,,i),fa[i]=i;
char op;
int x,y,z,ans=;
while(Q--)
{
scanf(" %c%d%d",&op,&x,&y),x^=ans,y^=ans;
if(op=='Q')
{
scanf("%d",&z),z^=ans;
int Fa=lca(x,y);
printf("%d\n",ans=b[tree::query(rt[x],rt[y],rt[Fa],rt[f[Fa][]],z,,p)]);
}
else{
G[x].push_back(y),G[y].push_back(x);
int fx=find(x),fy=find(y);
if(sz[fx]<sz[fy])swap(x,y),swap(fx,fy);
dfs(y,x,fx);
}
}
}
[Sdoi2013]森林(启发式合并+主席树)的更多相关文章
- BZOJ 3123 [SDOI2013] 森林 - 启发式合并 主席树
Description 给你一片森林, 支持两个操作: 查询$x$到$y$的$K$大值, 连接两棵树中的两个点 Solution 对每个节点$x$动态开权值线段树, 表示从$x$到根节点路径上权值出 ...
- 【BZOJ3123】[SDOI2013] 森林(启发式合并主席树)
点此看题面 大致题意: 给你一片森林,有两种操作:询问两点之间的第\(k\)小点权和在两棵树之间连一条边. 前置技能:树上主席树 做这道题目,我们首先要会树上主席树. 关于树上主席树,这有一道很好的例 ...
- bzoj 3674: 可持久化并查集加强版 (启发式合并+主席树)
Description Description:自从zkysb出了可持久化并查集后……hzwer:乱写能AC,暴力踩标程KuribohG:我不路径压缩就过了!ndsf:暴力就可以轻松虐!zky:…… ...
- BZOJ 2733 [HNOI2012]永无乡 - 启发式合并主席树
Description 1: 查询一个集合内的K大值 2: 合并两个集合 Solution 启发式合并主席树板子 Code #include<cstdio> #include<cst ...
- BZOJ3123: [Sdoi2013]森林(启发式合并&主席树)
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4813 Solved: 1420[Submit][Status ...
- [bzoj3123][洛谷P3302] [SDOI2013]森林(树上主席树+启发式合并)
传送门 突然发现好像没有那么难……https://blog.csdn.net/stone41123/article/details/78167288 首先有两个操作,一个查询,一个连接 查询的话,直接 ...
- 【bzoj3123】[Sdoi2013]森林 倍增LCA+主席树+启发式合并
题目描述 输入 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负 ...
- p3302 [SDOI2013]森林(树上主席树+启发式合并)
对着题目yy了一天加上看了一中午题解,终于搞明白了我太弱了 连边就是合并线段树,把小的集合合并到大的上,可以保证规模至少增加一半,复杂度可以是\(O(logn)\) 合并的时候暴力dfs修改倍增数组和 ...
- 洛谷 P3302 [SDOI2013]森林 Lebal:主席树 + 启发式合并 + LCA
题目描述 小Z有一片森林,含有N个节点,每个节点上都有一个非负整数作为权值.初始的时候,森林中有M条边. 小Z希望执行T个操作,操作有两类: Q x y k查询点x到点y路径上所有的权值中,第k小的权 ...
随机推荐
- 实验吧web-中-忘记密码了
打开网页,查看源代码,好像发现了管理员邮箱而且还是用vim编辑的. 我们提交一下这个邮箱,虽然提交成功了,但好像并没什么用. 我们随便提交一个,会弹出 看来好像还有个step2呢,我们查看源代码(在这 ...
- 使用eclipse创建maven时遇到的问题
转自https://www.cnblogs.com/hongmoshui/p/7994759.html 1.在eclipse中用maven创建项目,右键new>>Maven Proje ...
- 深入浅出Python装饰器
1.前言 装饰器是Python的特有的语法,刚接触装饰器的同学可能会觉得装饰器很难理解,装饰器的功能也可以不用装饰器实现,但是装饰器无疑是提高你Python代码质量的利器(尤其是使用在一些具有重复功能 ...
- opencv vs2013提示缺少Qedit.h问题
#pragma include_alias( "dxtrans.h", "qedit.h" ) #define __IDxtCompositor_INTERFA ...
- UVA 11922 伸展树Splay 第一题
上次ZOJ月赛碰到一个题目要求对序列中的某个区间求gcd,并且还要随时对某位数字进行修改 插入 删除,当时马上联想到线段树,但是线段树不支持增删,明显还是不可以的,然后就敲了个链表想暴力一下,结果TL ...
- 直击JDD | 徐雷:智能化零售,以技术为驱动力的突破路径
"京东零售已经成为一家典型的以技术驱动为主的零售公司".在11月19日召开的 2019京东全球科技探索者大会上,京东零售集团CEO徐雷首次阐释了京东零售的智能化零售路径. 徐雷指出 ...
- 吴裕雄--天生自然MySQL学习笔记:MySQL 删除数据表
MySQL中删除数据表是非常容易操作的, 但是在进行删除表操作时要非常小心,因为执行删除命令后所有数据都会消失. 语法 以下为删除MySQL数据表的通用语法: DROP TABLE table_nam ...
- getitem
#一般如果想使用索引访问元素时,就可以在类中定义这个方法(__getitem__(self, key) )class Foo(object): def __init__(self): self.dat ...
- 转载:微信小程序源码提取反编译
转载来源:www.51xuediannao.com/xiaochengxu/019c08cc.html 一.前言 微信小程序源码提取反编译,听起来很屌,其实还是简单的,基本是傻瓜式操作.要想拿到微信小 ...
- 从定时器的选型,到透过源码看XXL-Job(下)
透过源码看xxl-job (注:本文基于xxl-job最新版v2.0.2, quartz版本为 v2.3.1. 以下提到的调度中心均指xxl-job-admin项目) 上回说到,xxl-job是一个中 ...