CF 690C3. Brain Network (hard) from Helvetic Coding Contest 2016 online mirror (teams, unrated)
题目描述
Brain Network (hard) 这个问题就是给出一个不断加边的树,保证每一次加边之后都只有一个连通块(每一次连的点都是之前出现过的),问每一次加边之后树的直径。
算法
每一次增加一条边之后,树的直径长度要么不变,要么会增加1,并且如果树的直径长度增加1了,新的直径的端点其中一个必然是新增的点,而另一个是原来直径的某个端点。关于为什么可以这样做,在Quora上有个回答解释地不错,可以参考。
实现
所以这个问题其实就是要计算树上任意两个点的距离,LCA可以很轻松地处理。
可以一次性先把数据都读完,建树,因为每一次询问,后面加入的边不会对当前询问造成影响。
如果用二进制祖先那种搞法来算LCA的话,也可以每读一个新增点就去算一下,相当于是把原来的过程给拆开了。
下面是我的代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
const int N = 223456;
struct Edge {
int to, next;
} edge[N << 1];
int idx = 1, head[N];
void addEdge(int u, int v) {
edge[++idx].to = v;
edge[idx].next = head[u];
head[u] = idx;
}
void init() {
memset(head, 0, sizeof(head));
idx = 1;
}
int par[N][21];
int dep[N];
void dfs(int u, int fa, int d) {
dep[u] = d;
for (int k = head[u]; k; k = edge[k].next) {
int v = edge[k].to;
if (v == fa) continue;
par[v][0] = u;
dfs(v, u, d + 1);
}
}
void calc(int n) {
for (int i = 1; i <= 20; i++) {
for (int j = 1; j <= n; j++) {
par[j][i] = par[par[j][i - 1]][i - 1];
}
}
}
int kthA(int u, int k) {
for (int i = 20; i >= 0; i--) {
if (k >= (1 << i)) {
k -= (1 << i);
u = par[u][i];
}
}
return u;
}
int lca(int u, int v) {
if (dep[u] < dep[v])swap(u, v);
u = kthA(u, dep[u] - dep[v]);
if (u == v)return u;
for (int i = 20; i >= 0; i--) {
if (par[u][i] == par[v][i])continue;
u = par[u][i];
v = par[v][i];
}
return par[u][0];
}
bool update(int u, int v, int &k) {
int a = lca(u, v);
int d = dep[u] + dep[v] - 2 * dep[a];
if (d > k) {
k = d;
return true;
}
return false;
}
int a[N];
int main() {
int n;
scanf("%d", &n);
int u = 1, v = 1, cur = 0;
init();
for (int i = 2; i <= n; i++) {
scanf("%d", a + i);
addEdge(a[i], i);
}
dfs(1, -1, 0);
calc(n);
for (int i = 2; i <= n; i++) {
int nv = v;
if (update(u, i, cur)) {
nv = i;
}
if (update(v, i, cur)) {
u = v;
nv = i;
}
v = nv;
printf("%d ", cur);
}
puts("");
return 0;
}
CF 690C3. Brain Network (hard) from Helvetic Coding Contest 2016 online mirror (teams, unrated)的更多相关文章
- Helvetic Coding Contest 2016 online mirror C1
Description One particularly well-known fact about zombies is that they move and think terribly slow ...
- Helvetic Coding Contest 2016 online mirror A1
Description Tonight is brain dinner night and all zombies will gather together to scarf down some de ...
- Helvetic Coding Contest 2016 online mirror C2
Description Further research on zombie thought processes yielded interesting results. As we know fro ...
- Helvetic Coding Contest 2017 online mirror (teams allowed, unrated)
G. Fake News (easy) time limit per test 1 second memory limit per test 256 megabytes input standard ...
- Helvetic Coding Contest 2017 online mirror (teams allowed, unrated) J
Description Heidi's friend Jenny is asking Heidi to deliver an important letter to one of their comm ...
- Helvetic Coding Contest 2016 online mirror F1
Description Heidi has finally found the mythical Tree of Life – a legendary combinatorial structure ...
- Helvetic Coding Contest 2016 online mirror B1
Description The zombies are gathering in their secret lair! Heidi will strike hard to destroy them o ...
- Helvetic Coding Contest 2016 online mirror D1
Description "The zombies are lurking outside. Waiting. Moaning. And when they come..." &qu ...
- Helvetic Coding Contest 2017 online mirror (teams allowed, unrated) M
Description The marmots have prepared a very easy problem for this year's HC2 – this one. It involve ...
随机推荐
- ANdrod Studio查看Sha1的方法
在用Studio做开发中,有时候根据业务需求,需要集成一些SDk,举个例子,百度的鹰眼定位,当然还有很多,在创建项目的时候需要输入sha1值,这个sha1值的获取有多种方式,我记得百度有个检测,就可以 ...
- T——SQL基础语句(定义变量,赋值,取值,分支,循环,存储过程)
T--SQL基础语句 1.定义变量: declare @变量名 数据类型 ; declare @a int ; declare @b nvarchar(10) ; 2.赋值: 法1:set @变量名 ...
- 谈谈java中的volatile
内存可见性 留意复合类操作 解决num++操作的原子性问题 禁止指令重排序 总结 内存可见性 volatile是Java提供的一种轻量级的同步机制,在并发编程中,它也扮演着比较重要的角色.同synch ...
- Mybatis的@Options注解
mybatis的@Options注解能够设置缓存时间,能够为对象生成自增的key 第一个使用场景: 有一个表 CREATE TABLE instance ( instance_id BIGINT UN ...
- SpringMVC中@RequestBody引起的400异常处理,返回校验失败具体信息
问题 使用@RequestBody接收一个json数据的时候,如果传入的参数不符合条件,就会直接返回400的error page. 但究竟是为什么会400并没有抛出来.这对大量参数字段的我们来说,排错 ...
- cuda编程学习4——Julia
书上的例子编译会有错误,修改一下行即可. __device__ cuComplex(float a,float b):r(a),i(b){} /* ========================== ...
- Layoutinlater 转
http://blog.csdn.net/guolin_blog/article/details/12921889
- 实用 .htaccess 用法大全
这里收集的是各种实用的 .htaccess 代码片段,你能想到的用法几乎全在这里. 免责声明: 虽然将这些代码片段直接拷贝到你的 .htaccess 文件里,绝大多数情况下都是好用的,但也有极个别情况 ...
- ie旋转滤镜Matrix
旋转一个元素算是一个比较常见的需求了吧,在支持CSS3的浏览器中可以使用transform很容易地实现,这里有介绍:http://www.css88.com/archives/2168,这里有演示ht ...
- Windbg调试中遇到的问题
1.找不到符号文件 抓取完Dump后,打开WinDbg,Ctrl+D找到刚才抓取的Dump文件,报如下异常: *** ERROR: Symbol file could not be found. De ...