BZOJ 3910 并查集+线段树合并
思路:
1. 并查集+线段树合并
记得f[LCA]==LCA的时候 f[LCA]=fa[LCA]
2.LCT(并不会写啊...)
//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=;
int n,m,xx,yy,a,first[N],next[N*],v[N*],tot,deep[N],num[N],f[N],fa[N][];
long long ans;
int lca(int x,int y){
if(deep[x]<deep[y])swap(x,y);
for(int i=;~i;i--)if(deep[x]-(<<i)>=deep[y])x=fa[x][i];
if(x==y)return x;
for(int i=;~i;i--)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][];
}
void dfs(int x){for(int i=first[x];~i;i=next[i])if(v[i]!=fa[x][])deep[v[i]]=deep[x]+,fa[v[i]][]=x,dfs(v[i]);}
void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;}
int dis(int x,int y){return deep[x]+deep[y]-*deep[lca(x,y)];}
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
int main(){
memset(first,-,sizeof(first));
scanf("%d%d%d",&n,&m,&a);
for(int i=;i<n;i++){
scanf("%d%d",&xx,&yy),add(xx,yy),add(yy,xx);
}deep[]=,dfs();
for(int j=;j<=;j++)
for(int i=;i<=n;i++)
fa[i][j]=fa[fa[i][j-]][j-];
for(int i=;i<=m;i++)scanf("%d",&num[i]);
for(int i=;i<=n;i++)f[i]=i;
for(int i=;i<=m;i++){
if(find(num[i])==num[i]){
int LCA=lca(a,num[i]);
ans+=dis(a,num[i]);
for(int j=a;deep[j]>deep[LCA];j=find(fa[j][]))f[j]=LCA;
for(int j=num[i];deep[j]>deep[LCA];j=find(fa[j][]))f[j]=LCA;
if(f[LCA]==LCA)f[LCA]=fa[LCA][];
a=num[i];
}
}
printf("%lld\n",ans);
}
BZOJ 3910 并查集+线段树合并的更多相关文章
- bzoj2733 / P3224 [HNOI2012]永无乡(并查集+线段树合并)
[HNOI2012]永无乡 每个联通块的点集用动态开点线段树维护 并查集维护图 合并时把线段树也合并就好了. #include<iostream> #include<cstdio&g ...
- Codeforces Gym 101194G Pandaria (2016 ACM-ICPC EC-Final G题, 并查集 + 线段树合并)
题目链接 2016 ACM-ICPC EC-Final Problem G 题意 给定一个无向图.每个点有一种颜色. 现在给定$q$个询问,每次询问$x$和$w$,求所有能通过边权值不超过$w$的 ...
- BZOJ2733 [HNOI2012]永无乡(并查集+线段树合并)
题目大意: 在$n$个带权点上维护两个操作: 1)在点$u,v$间连一条边: 2)询问点$u$所在联通块中权值第$k$小的点的编号,若该联通块中的点的数目小于$k$,则输出$-1$: 传送门 上周的模 ...
- 【HNOI2012】永无乡 题解(并查集+线段树合并)
题目链接 给定一张含$n$个点$m$条边的无向图,每个点有一个重要指数$a_i$.有两种操作:1.在$x$和$y$之间连一条边:2.求$x$所在连通块中重要程度第$k$小的点. ----------- ...
- [BZOJ2733] [HNOI2012]永无乡(并查集 + 线段树合并)
传送门 一看到第k大就肯定要想到什么权值线段树,主席树,平衡树之类的 然后就简单了 用并查集判断连通,每个节点建立一颗权值线段树,连通的时候直接合并即可 查询时再二分递归地查找 时间复杂度好像不是很稳 ...
- BZOJ- 2733: 永无乡 (并查集&线段树合并)
题意:给定N个节点,K次操作,操作有两种,1是合并两个集合,2是求某个集合的第K大(从小到大排序). 思路:合并只要启发式即可.此题可以用线段树,保存1到N的排序的出现次数和. 复杂度O(NlogN) ...
- UVA1455 - Kingdom(并查集 + 线段树)
UVA1455 - Kingdom(并查集 + 线段树) 题目链接 题目大意:一个平面内,给你n个整数点,两种类型的操作:road x y 把city x 和city y连接起来,line fnum ...
- 并查集&线段树&树状数组&排序二叉树
超级无敌巨牛逼并查集(带权并查集)https://vjudge.net/problem/UVALive-4487 带删点的加权并查集 https://vjudge.net/problem/UVA-11 ...
- 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)
题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...
随机推荐
- windows 实时性
在硬件编程时,大部分非智能硬件并没有主动通知反馈功能,需要PC主动轮询状态寄存器去查询硬件状态.对于运动类控制器,查询的时机(间隔)在一定程度上影响着准确率与系统负载.即使不考虑系统负载,在1000H ...
- AdminLTE框架基础布局使用
boxbox-solid:去掉顶部边框线box-headerwith-border:添加头底部边框线 按钮:—— btn btn-default 默认<div class="btn-g ...
- windows server 2008如何显示后缀名
任意打开一个文件----点击左上角有个[组织]---[文件夹和搜索选项]---[查看]----去掉勾[隐藏已知文件类型的扩展名]---确定即可
- GFS分布式文件系统环境部署与管理
Gluster分布式文件系统 准备环境五台虚拟机 创建/gfs目录,把软件包全部拷贝目录 把yum仓库的源放进bak下才能执行以下脚本 并指定主机名这四台机器都要执行脚本 [root@localhos ...
- esp32使iOS 获取蓝牙外设的Mac地址
最近在做一个需要上下位机的项目,我负责的任务下位机,使用的主控芯片是esp32.这个项目中有一项是需要手机扫描二维码然后连接作为esp32的蓝牙.二维码中包含了mac地址信息,在手机扫描周围设备的时候 ...
- es6-Symbol用法
1.symbol概念 这种数据类型提供独一无二值 比如,在JS中,我可以通过数据类型生成变量a=number05,也可以生成b=nubmer05,这两个变量可以说是相等的. 但是用symbol生成的值 ...
- html第四节课
css CSS(Cascading Style Sheet,叠层样式表),作用是美化HTML网页. /*注释区域*/ 此为注释语法 一.样式表 (一)样式表的分类 1.内联样式表 和HTML联合 ...
- 递归、作用域、生命周期(day09)
数组可以作为形式参数使用 数组做形式参数的时候真正的形式参数并 不是数组而是一个可以作为数组使用的 变量 数组形式参数里包含的存储区都不是被调用 函数提供的 声明数组形式参数的时候可以省略中括号 里的 ...
- linux根据进程名字杀死进程
ps -ef | grep procedure_name | grep -v grep | awk '{print $2}' | xargs kill -9 Linux Shell脚本实现根据进程名杀 ...
- 【习题 4-2 Uva201】Squares
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 注意那个星号的数量... 然后V x y的话,是从(y,x)向(y+1,x)连线. H x y才是从(x,y)向(x,y+1)连线 ...