[传送门]

考虑计算直径的 dp 方法。
$d[u]$ 表示以 $u$ 为根的子树能 $u$ 能走到的最远距离
$dp[u]$ 表示以 $u$ 为根的子树的直径
那么每次dfs一个子节点后
$dp[u] = max(d[u] + d[v] + 1, dp[u])$
$d[u] = max(d[v] + 1, d[u])$
注意顺序一反就错了。
这里并没有考虑到 $u$ 是某个节点的儿子是,路径可以往父节点走的情况,但是这是对的。
因为如果这种情况存在,那么我们在递归回父节点是就可以更新到。所以直径取最后 dp 数组的最大值是对的。
回到这个题,因为数据的生成方式,树高不超过 $log n$,并且第 $i$ 条边一定有 第 $i + 1$个节点。
如果从 $[x, n - 1]$ 这棵树已经建好了,那么加入第 $x - 1$ 条边就是把 $p[x - 1]$ 和 $x$ 这两个节点形成的连通块进行合并。
深度不超过 $log n$,那么可以暴力一点。
将询问离线。按 $r$ 从大到小排序,考虑倒序建这棵树。
$f[u][i]$ 表示以 $u$ 为根的子树内 $u$ 能到达的最远距离为 $i$ 时 $r$ 的最小值。即在 $[l, f[u][i]]$ $u$ 能往下走 $i$ 步。
$g[i]$ 表示树的直径至少为 $i$ 时 最小的 $r$。即在 $[l, g[i]]$ 树的直径至少为 $i$。
倒序加入一条边,相当于两棵树合并,那么就先更新 $g$ 数组,具体更新方式如 $dp$ 的更新方式,分别枚举高度进行合并。
$g[i + j + 1] = min(g[i + j + 1], max(f[u][i], f[v][i], v - 1))$ $v-1$ 即为当前加入的边。
在更新 $u$,即 $u$ 为 $v$ 的父亲。
$f[u][i] = min(f[u][i], max(f[v][i - 1], v - 1))$
求答案就枚举高度看 $g$ 数组是否小于当前 $r$

#include <bits/stdc++.h>
using namespace std; const int N = 5e5 + ;
const int dep = ; struct In {
int l, r;
bool operator < (const In &rhs) const {
if (l == rhs.l) return r > rhs.r;
return l > rhs.l;
}
} que[N]; int f[N][dep + ];
int g[dep * ];
int p[N], n; void add(int u, int v) {
for (int i = ; i < dep; i++) if (f[u][i] < n)
for (int j = ; j < dep; j++)
g[i + j + ] = min(g[i + j + ], max(f[u][i], max(f[v][j], v - )));
for (int i = ; i < dep; i++)
f[u][i] = min(f[u][i], max(f[v][i - ], v - ));
} int main() {
scanf("%d", &n);
memset(f, 0x3f, sizeof(f));
for (int i = , x; i < n; i++)
scanf("%d%d", p + i, &x), f[i][] = ;
f[n][] = ;
memset(g, 0x3f, sizeof(g));
int q;
scanf("%d", &q);
for (int i = ; i <= q; i++)
scanf("%d%d", &que[i].l, &que[i].r);
sort(que + , que + + q);
int now = n - ;
int ans = ;
for (int i = ; i <= q; i++) {
while (now && now >= que[i].l) {
add(p[now], now + );
now--;
}
for (int k = dep * ; k >= ; k--) {
if (g[k] <= que[i].r) {
ans += k;
break;
}
}
}
printf("%d\n", ans);
return ;
}

51nod1803 森林直径的更多相关文章

  1. BZOJ1791[Ioi2008]Island 岛屿 ——基环森林直径和+单调队列优化DP+树形DP

    题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...

  2. 2021.08.09 P7238 迷失森林(树的直径)

    2021.08.09 P7238 迷失森林(树的直径) P7238 「DCOI」迷失森林 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.树的直径两种求法:两次dfs.树 ...

  3. 『Island 基环树直径』

    Island(IOI 2008) Description 你准备浏览一个公园,该公园由 N 个岛屿组成,当地管理部门从每个岛屿 i 出发向另外一个岛屿建了一座长度为 L_i 的桥,不过桥是可以双向行走 ...

  4. 【FJWC 2019】 森林

    [FJWC 2019] 森林 样例输入 0 5 1 0 0 2 样例输出 1 2 3 3 我们发现,答案就是直径加上直径上某个点出发,不经过其他直径上的点的最长链.这里的直径可以是任意一条直径. 首先 ...

  5. 51Nod1367 完美森林 贪心

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1367.html 题目传送门 - 51Nod1367 题意 有一棵N个点的树,树中节点标号依次为0,1 ...

  6. D4 树的直径、重心以及基环树

    第一题第二题鉴上我前几篇博客poj1985 poj1849:https://www.cnblogs.com/Tyouchie/p/10384379.html 第三题:数的重心:poj1655 来自sj ...

  7. 求树的直径+并查集(bfs,dfs都可以)hdu4514

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 这题主要是叫我们求出树的直径,在求树的直径之前要先判断一下有没有环 树的直径指的就是一棵树上面距 ...

  8. 【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT

    题目描述 给你 $n$ 个点,支持 $m$ 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. $n\le 3\times 10^5$ ,$ ...

  9. Codeforces 455C Civilization:树的直径 + 并查集【合并树后直径最小】

    题目链接:http://codeforces.com/problemset/problem/455/C 题意: 给你一个森林,n个点,m条边. 然后有t个操作.共有两种操作: (1)1 x: 输出节点 ...

随机推荐

  1. Spring Cloud OkHttp设计原理

    Spring Cloud 框架最底层核心的组件就是服务调用方式,一般Spring Cloud框架采用的是HTTP的调用框架,本文将在 Spring Cloud应用场景下,介绍组件OkHttp3的设计原 ...

  2. 最新修改Oracle10gscott用户

    1.以system登录及输入自己设置口令; 2.更换sysdba身份: conn system/orcl as sysdba; 3.解锁scott用户(因装好默认是锁定的): alter user s ...

  3. mysql 中的 not like 另一种简化方法。

    第一种 not like 方法 select * from table where `zongbu` not like '%北京%' and `zongbu` not like '%上海%' and ...

  4. opencv常用数据结构

    2019/10/29 1.Mat 成员函数:cols.rows.channels.ptr获取任意行的首地址.at处理像素 2.InputArray/OutArray相当于Mat 2019/11/4 1 ...

  5. [Leetcode] Binary Tree Pruning

    題目是說,如果左右子樹都不存在又自已為0,就去掉那個子樹(設為null) recursive後序,左子樹,右子樹,然後是根 自已同時又是別人的子樹,所以要告訢根自已是不是存在 從a開始,左右子樹都不存 ...

  6. Vert.x Web

    https://vertx.io/docs/vertx-web/java/ Vert.x-Web是一组用于使用Vert.x构建Web应用程序的构建块.将其视为瑞士军刀,用于构建现代,可扩展的网络应用程 ...

  7. Spring的配置文件找不到元素 'beans' 的声明

    Spring的配置文件找不到元素 'beans' 的声明 一般是由Spring的版本导致的,你可以尝试使用如下的某一种. <?xml version="1.0" encodi ...

  8. formData详细使用教程

    formData是ajax2.0(XMLHttpRequest Level2)新提出的接口,利用FormData对象可以将form表单元素的name与value进行组合,实现表单数据的序列化,从而介绍 ...

  9. MySQL导入数据报错Got a packet bigger than‘max_allowed_packet’bytes错误的解决方法

    由于max_allowed_packet的值设置过小的原因,只需要将max_allowed_packet值设置大一点就OK了.通过终端进入mysql控制台,输入如下命令可以查看max_allowed_ ...

  10. Android源码分析(三)-----系统框架设计思想

    一 : 术在内而道在外 Android系统的精髓在源码之外,而不在源码之内,代码只是一种实现人类思想的工具,仅此而已...... 近来发现很多关于Android文章都是以源码的方向入手分析Androi ...