火车 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. 手机端左右滑动,不用写js(只有页面切换到移动端可以看)

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  2. Java编程思想总结笔记Chapter 5

    初始化和清理是涉及安全的两个问题.本章简单的介绍“垃圾回收器”及初始化知识. 第五章  初始化与清理 目录:5.1 用构造器确保初始化5.2 方法重载5.3 默认构造器5.4 this关键字5.5 清 ...

  3. spark 学习路线及参考课程

    一.Scala编程详解: 第1讲-Spark的前世今生 第2讲-课程介绍.特色与价值 第3讲-Scala编程详解:基础语法 第4讲-Scala编程详解:条件控制与循环 第5讲-Scala编程详解:函数 ...

  4. windows保存tomcat的控制台日志到文件

    startup.bat修改:call "%EXECUTABLE%" start %CMD_LINE_ARGS%改为:call "%EXECUTABLE%" ru ...

  5. OJB

    OJB 编辑 本词条缺少名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! 对象关系桥(OJB)是一种对象关系映射工具,它能够完成从Java对象到关系数据库的透明存储.   英文名 OJB ...

  6. js进行的一些判断

    表达式 "^\\d+$" //非负整数(正整数 + 0) "^[0-9]*[1-9][0-9]*$" //正整数 "^((-\\d+)|(0+))$& ...

  7. Spring Data Redis入门示例:基于Jedis及底层API (二)

    使用底层API:RedisConnectionFactory和RedisConnection可以直接操作Redis,下面是一个简单的例子: ### Maven依赖 <properties> ...

  8. jquery data属性 attr vs data

    html5的自定义data属性相信大家都不会陌生,有了它你可以绑定所需的数据到指定元素上.然后通过jquery设置.获取数据,简直开心的不行啊.想到设置.获取元素属性值,大家一定首先想到了jquery ...

  9. IO之Print流举例

    import java.io.*; public class TestPrintStream1 { public static void main(String[] args) { PrintStre ...

  10. 微信小程序 video组件 不随页面滚动

    1.页面初始化(滚动前)时,video所在位置 2.页面滚动后,video视频组件所在位置 看了别人家的小程序并不会出现这种状况.最后检查发现,是页面包裹层设置了 height:100% 导致的 顺便 ...