[bzoj3910]火车_并查集_倍增LCA
火车 bzoj-3910
题目大意:给定一棵n个节点的树,你需要顺次经过m个互不相同的节点,如果一个节点在之前的路径上被经过过,它不必再被特意经过。问走过的路径长度。
注释:$1\le n\le 5\cdot 10^5$,$1\le m\le 4\cdot 10^5$。
想法:
考场上切了/xyx
考虑暴力:顺次枚举所有必经点然后暴力爬,标记为经过过即可,总时间复杂度为O(nm)。
我们发现如果两个点之间的一些路径是vis那么他们没有必要被在此枚举一遍。
所以如果一个节点被到达过我们将它的并查集内的Father连向它树上的父亲,表示这个节点已经被删去了。
再次遍历的时候我们爬并查集就行了。
更新答案的话我们用倍增求出两点的LCA,用dep值计算路径长度累加答案即可。
显然每个点只会被删除一次,而且只会被遍历一次因为遍历之后就会被删掉。
故总时间复杂度为O(n+m)。
最后,附上丑陋的代码... ...
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 500010
using namespace std;
typedef long long ll;
int to[N<<1],nxt[N<<1],head[N],tot;
int dep[N],f[25][N],F[N];
bool vis[N]; int go[N];
inline void add(int x,int y) {to[++tot]=y; nxt[tot]=head[x]; head[x]=tot;}
int find(int x) {return F[x]==x?x:F[x]=find(F[x]);}
void dfs(int pos,int fa)
{
// puts("Fuck");
dep[pos]=dep[fa]+1; f[0][pos]=fa; for(int i=1;i<=23;i++) f[i][pos]=f[i-1][f[i-1][pos]];
for(int i=head[pos];i;i=nxt[i]) if(to[i]!=fa) dfs(to[i],pos);
}
int lca(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=23;~i;i--) if(dep[f[i][x]]>=dep[y]) x=f[i][x];
if(x==y) return x;
for(int i=23;~i;i--) if(f[i][x]!=f[i][y]) x=f[i][x],y=f[i][y];
return f[0][x];
}
inline void update(int x)
{
vis[x]=true; for(int i=head[x];i;i=nxt[i]) if(to[i]!=f[0][x]) F[to[i]]=x;
}
void Lca(int x,int y)
{
// puts("Fuck");
int z=lca(x,y);
while(dep[x]>dep[z])
{
update(x); x=f[0][find(x)];
}
// printf("Fuck %d\n",y);
while(dep[y]>dep[z])
{
// printf("Fuck %d\n",y);
update(y);
// printf("Shit %d\n",z);
y=f[0][find(y)];
// printf("Shit %d\n",z);
}
update(z);
// puts("Fuck");
}
int main()
{
// freopen("airline.in","r",stdin);
// freopen("airline.out","w",stdout);
int x,y; ll ans=0;
int n,m,a; scanf("%d%d%d",&n,&m,&a); int pre=a; for(int i=1;i<n;i++) {scanf("%d%d",&x,&y); add(x,y); add(y,x);}
for(int i=1;i<=n;i++) F[i]=i;
dfs(1,1);
// printf("%d %d %d\n",lca(1,2),lca(2,3),lca(3,4));
for(int i=1;i<=m;i++) scanf("%d",&go[i]); for(int i=1;i<=m;i++)
{
if(!vis[go[i]])
{
// printf("%d\n",go[i]);
ans+=dep[pre]+dep[go[i]]-dep[lca(pre,go[i])]*2;
// printf("%d %d %d %d %d %d\n",pre,go[i],lca(pre,go[i]),dep[pre],dep[go[i]],dep[lca(pre,go[i])]);
Lca(pre,go[i]);
pre=go[i];
}
}
printf("%lld\n",ans);
return 0;
}
小结:比较有趣的一道题。
[bzoj3910]火车_并查集_倍增LCA的更多相关文章
- poj1182食物链_并查集_挑战程序设计竞赛例题
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 65534 Accepted: 19321 Description ...
- BZOJ_3362_[Usaco2004 Feb]Navigation Nightmare 导航噩梦_并查集
BZOJ_3362_[Usaco2004 Feb]Navigation Nightmare 导航噩梦_并查集 Description 农夫约翰有N(2≤N≤40000)个农场,标号1到N,M( ...
- BZOJ_2303_[Apio2011]方格染色 _并查集
BZOJ_2303_[Apio2011]方格染色 _并查集 Description Sam和他的妹妹Sara有一个包含n × m个方格的 表格.她们想要将其的每个方格都染成红色或蓝色. 出于个人喜好, ...
- BZOJ_1015_[JSOI2008]星球大战_并查集
BZOJ_1015_[JSOI2008]星球大战_并查集 题意:很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的 机遇,一支反抗军摧毁了帝国的超级武器, ...
- BZOJ_1998_[Hnoi2010]Fsk物品调度_并查集+置换
BZOJ_1998_[Hnoi2010]Fsk物品调度_并查集+置换 Description 现在找工作不容易,Lostmonkey费了好大劲才得到fsk公司基层流水线操作员的职位.流水线上有n个位置 ...
- BZOJ_2443_[Usaco2011 Open]奇数度数 _并查集+树形DP
BZOJ_2443_[Usaco2011 Open]奇数度数 _并查集. Description 奶牛们遭到了进攻!在他们的共和国里,有N(1 <= N <=50,000)个城市,由M(1 ...
- 【BZOJ4569】萌萌哒(并查集,倍增)
[BZOJ4569]萌萌哒(并查集,倍增) 题面 BZOJ 题意: 有一个长度为\(n\)的数 给定\(m\)个限制条件 每次限制\(l1-r1\)与\(l2-r2\)是相同的 求出方案数 题解 如果 ...
- [Comet OJ - Contest #6 D][48D 2280]另一道树题_并查集
另一道树题 题目大意: 数据范围: 题解: 这个题第一眼能发现的是,我们的答案分成两种情况. 第一种是在非根节点汇合,第二种是在根节点汇合. 尝试枚举在第几回合结束,假设在第$i$回合结束的方案数为$ ...
- hdu 2473 Junk-Mail Filter(并查集_虚节点)2008 Asia Regional Hangzhou
感觉有些难的题,刚开始就想到了设立虚节点,但是实现总是出错,因为每次设立了虚节点之后,无法将原节点和虚节点分开,导致虚节点根本无意义. 以上纯属废话,可以忽略…… 题意—— 给定n个点(0, 1, 2 ...
随机推荐
- 纯CSS写的对勾样式
& .cicle{ position: relative; float: right; margin-right: -1rem; ...
- 短视频SDK简单易用——来自RDSDK.COM
锐动天地为开发者提供短视频编辑.视频直播.特效.录屏.编解码.视频转换,等多种解决方案,涵盖PC.iOS.Android多平台.以市场为导向,不断打磨并创新技术,在稳定性,兼容性,硬件设备效率优化上千 ...
- javscript 导出html中的table到excel
<script language="JavaScript" type="text/javascript"> /* * 默认转换实现函数,如果需要其他 ...
- Android图片压缩,不失真,上线项目
当然了,图片压缩是利用了libjpeg库的基础上,牛逼的同学可以自行生成so.jar.在此给出一个链接: http://www.cnblogs.com/hrlnw/p/4403334.html 在生成 ...
- EasyUI edatagrid插件使用小计
html片段 <table id="menuview" style="width:100%"> <thead> <tr> & ...
- C/C++ 函数模板、全局变量、register、存储周期
1.函数声明时可以简写,如: int max(int,int): 2.函数模板: 格式: template <typename haha>或template <class haha& ...
- [安卓开发板]迅为IMX6 四核Android开发板
工业级核心板-Android开发板 10层高速PCB设计,充分保证电磁兼容 处理器:开发板默认是四核商业扩展级芯片,可根据用户需求更换单核.双核.工业级.汽车级处理器,批量更省成本. 扩展引脚:320 ...
- Swift 中的值类型与引用类型
顶级修饰 次级修饰 赋值类型 存储类型 值类型 值类型 深拷贝 栈 值类型 引用类型 浅拷贝 堆 引用类型 值类型 浅拷贝 堆 引用类型 引用类型 浅拷贝 堆 复合引用类型会改变内部值类型的存储行 ...
- swift 与 @objc
Objective-C entry points https://github.com/apple/swift-evolution/blob/master/proposals/0160-objc-in ...
- MySql(一)mysql服务的基本操作及环境配置
MySQL服务的启动开始–>计算机–>右键选择管理–>双击打开服务和应用程序–>双击服务–>找到MySQL的服务名称(我的是MySQL56),右键选择启动即可 通过命令行 ...