BZOJ3123:[SDOI2013]森林——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=3123
https://www.luogu.org/problemnew/show/P3302

树上主席树操作方法看:http://www.cnblogs.com/luyouqi233/p/8159528.html
这题要动态树,显然不可能LCT套主席树啊。
那我们完全可以启发式合并一下主席树。
剩下的操作就很简单了。
(然而我debug两个小时才发现我n定义了两个emmmm)
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cctype>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=8e4+;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct tree{
int l,r,sum;
}tr[N*];
struct node{
int to,nxt;
}edge[N*];
int a[N],b[N],rt[N],pool,n,m;
int dep[N],anc[N][],son[N];
int cnt,head[N],fa[N],vis[N],tot;
inline void add(int u,int v){
edge[++cnt].to=v;edge[cnt].nxt=head[u];head[u]=cnt;
}
inline void insert(int y,int &x,int l,int r,int p){
tr[x=++pool]=tr[y];tr[x].sum++;
if(l==r)return;
int mid=(l+r)>>;
if(p<=mid)insert(tr[y].l,tr[x].l,l,mid,p);
else insert(tr[y].r,tr[x].r,mid+,r,p);
}
inline int query(int nl,int nr,int nm,int nfm,int l,int r,int k){
if(l==r)return l;
int delta=tr[tr[nl].l].sum+tr[tr[nr].l].sum-tr[tr[nm].l].sum-tr[tr[nfm].l].sum;
int mid=(l+r)>>;
if(delta>=k)return query(tr[nl].l,tr[nr].l,tr[nm].l,tr[nfm].l,l,mid,k);
else return query(tr[nl].r,tr[nr].r,tr[nm].r,tr[nfm].r,mid+,r,k-delta);
}
inline void LSH(){
sort(b+,b+m+);
m=unique(b+,b+m+)-b-;
for(int i=;i<=n;i++){
a[i]=lower_bound(b+,b+m+,a[i])-b;
}
return;
}
inline int LCA(int i,int j){
if(dep[i]<dep[j])swap(i,j);
for(int k=;k>=;k--){
if(dep[anc[i][k]]>=dep[j])i=anc[i][k];
}
if(i==j)return i;
for(int k=;k>=;k--){
if(anc[i][k]!=anc[j][k])i=anc[i][k],j=anc[j][k];
}
return anc[i][];
}
int find(int x){
if(fa[x]==x)return x;
return fa[x]=find(fa[x]);
}
void dfs(int u,int f,int root){
anc[u][]=f;
for(int k=;k<=;k++)
anc[u][k]=anc[anc[u][k-]][k-];
son[root]++;dep[u]=dep[f]+;fa[u]=root;vis[u]=;
insert(rt[f],rt[u],,m,a[u]);
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v!=f)dfs(v,u,root);
}
return;
}
int main(){
read();
n=read();int e=read(),T=read(),last=;
for(int i=;i<=n;i++)
a[i]=b[++m]=read(),fa[i]=i;
LSH();
for(int i=;i<=e;i++){
int x=read(),y=read();
add(x,y);add(y,x);
}
for(int i=;i<=n;i++)
if(!vis[i]){
dfs(i,,++tot);fa[tot]=tot;
}
for(int i=;i<=T;i++){
char ch=getchar();
while(ch!='Q'&&ch!='L')ch=getchar();
if(ch=='Q'){
int x=read()^last,y=read()^last,k=read()^last;
int t=LCA(x,y),ft=anc[t][];
printf("%d\n",last=b[query(rt[x],rt[y],rt[t],rt[ft],,m,k)]);
}else{
int x=read()^last,y=read()^last;
add(x,y);add(y,x);
int u=find(x),v=find(y);
if(son[u]<son[v]){
swap(u,v);
swap(x,y);
}
dfs(y,x,u);
}
}
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
BZOJ3123:[SDOI2013]森林——题解的更多相关文章
- [BZOJ3123][Sdoi2013]森林 主席树+启发式合并
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 第一行包含一个正整数testcase,表示当 ...
- [bzoj3123][Sdoi2013]森林_主席树_启发式合并
森林 bzoj-3123 Sdoi-2013 题目大意:给定一片共n个点的森林,T个操作,支持:连接两个不在一棵树上的两个点:查询一棵树上路径k小值. 注释:$1\le n,T \le 8\cdot ...
- BZOJ3123: [Sdoi2013]森林(启发式合并&主席树)
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4813 Solved: 1420[Submit][Status ...
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- 【主席树 启发式合并】bzoj3123: [Sdoi2013]森林
小细节磕磕碰碰浪费了半个多小时的时间 Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M ...
- bzoj3123 [Sdoi2013]森林 树上主席树+启发式合并
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3123 题解 如果是静态的查询操作,那么就是直接树上主席树的板子. 但是我们现在有了一个连接两棵 ...
- bzoj3123: [Sdoi2013]森林
题面传送门 复出的第一道题.. md就遇到坑了.. 简单来说就是可持久化线段树+启发式合并啊.. 感觉启发式合并好神奇好想学 每一次建边就暴力合并,每一个节点维护从根到它的权值线段树 按照题面的话最省 ...
- BZOJ3123[Sdoi2013]森林——主席树+LCA+启发式合并
题目描述 输入 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负 ...
- bzoj千题计划258:bzoj3123: [Sdoi2013]森林
http://www.lydsy.com/JudgeOnline/problem.php?id=3123 启发式合并主席树 #include<cmath> #include<cstd ...
随机推荐
- Linux命令非常全
最近都在和Linux打交道,感觉还不错.这也是很多人喜欢linux的原因,比较短小但却功能强大.我将我了解到的命令列举一下,仅供大家参考: 系统信息 arch 显示机器的处理器架构(1) uname ...
- 三年同行,质造未来,腾讯WeTest五大服务免费体验
WeTest 导读 2018年10月26日,腾讯WeTest将正式迎来三周岁生日.三周年庆典期间,只要在WeTest平台注册的用户,均可免费体验标准兼容.云真机.压测大师.手游安全扫描.应用安全扫描等 ...
- 「日常训练」All Friends(POJ-2989)
题意 分析 代码 #include <iostream> #include <cstring> #include <algorithm> #define MP ma ...
- selenium--特殊元素定位
该篇博客总结特殊元素(select.radio\checkbox.时间控件.文件上传.图片验证码.模拟鼠标操作.Js 或 JQuery调用)操作. 1.select @Test public void ...
- MySQL☞lower函数
lower(列名/字符串):将大写字母改成小写字母 格式: select lower(列名/字符串) from 表名 如下图:
- 第五模块:WEB开发基础 第3章·BootStrap&JQuery开发
01-JQuery介绍 02-jQuery文件引入和加载的区别 03-jQuery的基础选择器 04-jQuery的层级选择器 05-jQuery的基本过滤选择器 06-jQuery的属性选择器 07 ...
- unity中虚拟摇杆的实现
实现效果: 实现: 使用NGUI添加虚拟摇杆背景和其子物体按钮,为按钮Attach boxcollider和ButtionScript.为按钮添加如下脚本: 注意:其中的静态属性可以在控制物体移动的 ...
- python 终极篇 --- django 路由系统
URL配置 基本格式: from django.conf.urls import url urlpattern ...
- spark写入ES(动态模板)
使用es-hadoop插件,主要使用elasticsearch-spark-20_2.11-6.2.x.jar 官网:https://www.elastic.co/guide/en/elasticse ...
- 【zabbix 监控】第二章 安装测试被监控主机
客户端安装测试 一.准备两台被监控主机,分别做如下操作: web129:192.168.19.129 web130:192.168.19.130 [root@web129 ~]#yum -y inst ...