火车 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的更多相关文章

  1. poj1182食物链_并查集_挑战程序设计竞赛例题

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 65534   Accepted: 19321 Description ...

  2. BZOJ_3362_[Usaco2004 Feb]Navigation Nightmare 导航噩梦_并查集

    BZOJ_3362_[Usaco2004 Feb]Navigation Nightmare 导航噩梦_并查集 Description     农夫约翰有N(2≤N≤40000)个农场,标号1到N,M( ...

  3. BZOJ_2303_[Apio2011]方格染色 _并查集

    BZOJ_2303_[Apio2011]方格染色 _并查集 Description Sam和他的妹妹Sara有一个包含n × m个方格的 表格.她们想要将其的每个方格都染成红色或蓝色. 出于个人喜好, ...

  4. BZOJ_1015_[JSOI2008]星球大战_并查集

    BZOJ_1015_[JSOI2008]星球大战_并查集 题意:很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的 机遇,一支反抗军摧毁了帝国的超级武器, ...

  5. BZOJ_1998_[Hnoi2010]Fsk物品调度_并查集+置换

    BZOJ_1998_[Hnoi2010]Fsk物品调度_并查集+置换 Description 现在找工作不容易,Lostmonkey费了好大劲才得到fsk公司基层流水线操作员的职位.流水线上有n个位置 ...

  6. BZOJ_2443_[Usaco2011 Open]奇数度数 _并查集+树形DP

    BZOJ_2443_[Usaco2011 Open]奇数度数 _并查集. Description 奶牛们遭到了进攻!在他们的共和国里,有N(1 <= N <=50,000)个城市,由M(1 ...

  7. 【BZOJ4569】萌萌哒(并查集,倍增)

    [BZOJ4569]萌萌哒(并查集,倍增) 题面 BZOJ 题意: 有一个长度为\(n\)的数 给定\(m\)个限制条件 每次限制\(l1-r1\)与\(l2-r2\)是相同的 求出方案数 题解 如果 ...

  8. [Comet OJ - Contest #6 D][48D 2280]另一道树题_并查集

    另一道树题 题目大意: 数据范围: 题解: 这个题第一眼能发现的是,我们的答案分成两种情况. 第一种是在非根节点汇合,第二种是在根节点汇合. 尝试枚举在第几回合结束,假设在第$i$回合结束的方案数为$ ...

  9. hdu 2473 Junk-Mail Filter(并查集_虚节点)2008 Asia Regional Hangzhou

    感觉有些难的题,刚开始就想到了设立虚节点,但是实现总是出错,因为每次设立了虚节点之后,无法将原节点和虚节点分开,导致虚节点根本无意义. 以上纯属废话,可以忽略…… 题意—— 给定n个点(0, 1, 2 ...

随机推荐

  1. mysql 忘记密码 登陆+修改密码

    step1: 苹果->系统偏好设置->最下边点mysql 在弹出页面中 关闭mysql服务(点击stop mysql server) step2: 进入终端输入:cd /usr/local ...

  2. 微信官方UI库—WeUI

    WeUI 为微信 Web 服务量身设计 概述 WeUI是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信 Web 开发量身设计,可以令用户的使用感知更加统一.包含button.cell ...

  3. R in action读书笔记(10)-第八章:回归-- 异常观测值 改进措施

    8.4 异常观测值 8.4.1 离群点 car包也提供了一种离群点的统计检验方法.outlierTest()函数可以求得最大标准化残差绝对值Bonferroni调整后的p值: > library ...

  4. Python+CGI,在Windows上快速部署Python到IIS

    通过CGI,我们可以快速在Windows上部署Python 1. Windows安装IIS服务 2. 在IIS里打开“ISAPI和CGI限制”->添加,路径=python.exe的完全路径+&q ...

  5. cf536c——思路题

    题目 题目:Lunar New Year and Number Division 题目大意:给定一个数字序列,可以任意分组(可调整顺序),但每组至少两个,求每组内数字和的平方的最小值 思路 首先,易证 ...

  6. 手机端打开调试工具,模拟console.log

    将下列代码考入需要调试页面即可 <script src="//cdn.jsdelivr.net/npm/eruda"></script> <scrip ...

  7. sh InvocationTargetException

    话题引入: 使用hibernate+struts框架开发项目时,使用占位符时,系统抛出如下异常: Exception: java.lang.reflect.InvocationTargetExcept ...

  8. mysql字符集乱码问题

    程序错误截图如下: 分析:我们mysql数据库没有设置默认编码, 导致创建的库字符集为 latin1,然而我们创建表的时候,指定字符集为其他的,比如utf8 我的解决思路:把数据库的编码修改为utf8 ...

  9. WPF学习- AllowDrop 用户控件启用拖放功能

    知识点: 创建自定义用户控件(UserControl) 使用户控件成为拖动源 使用户控件成为放置目标 使面板能够接收从用户控件放置的数据 创建项目: 1.新建WPF项目(Wpf-AllowDrop) ...

  10. mysql 添加记录或者删除记录

    insert into tableName (prod1,pord2,... ) values (v1,v2,...) [,(v1,v2,...),(v1,v2,...)] 程度从强到弱 1.drop ...