[传送门]

考虑计算直径的 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. [转帖]Linux操作系统定时任务系统 Cron 入门0

    Linux操作系统定时任务系统 Cron 入门 https://www.cnblogs.com/zhuiluoyu/p/5646400.html   cron是一个linux下的定时执行工具,可以在无 ...

  2. Range Sum Query - Mutable 精简无递归线段树

    操作: 单点更新,区间求和 区间求和:如sum [3,10) 需要对19,5,12,26节点求和即可. 观察可知,左端点为右子节点(奇数)时直接相加,右端点为左子节点(偶数)时直接相加,两边向中间移动 ...

  3. BussinessSkinForm 入门教程

    BussinessSkinForm 入门教程 By 刘家君(qufo) 作者:刘家君 工作单位:福建省 泉州鹭燕医药有限公司 职务:网络管理员 网名:qufo Mail:qufo@tom.com,qu ...

  4. python 笔记——生成器和迭代器

    #-*- coding:utf-8 -*- a=[1,2,3,4] for i,j in enumerate(a): print i,j '''只有ij时,''' a=[1,2,3,4] for i ...

  5. vue-cli中跨域问题解决方法

    webpack提供了配置代理的方法解决跨域 1 在vue-cli项目中打开webpack.dev.cof.js,如下 2 打开conifg目录下的index.js,在 proxyTable中进行配置 ...

  6. - instanceof 和 isInstance 强转 类型 class MD

    目录 目录 instanceof 和 isInstance 强转 类型 class MD 简介 测试案例 继承关系 测试代码 打印结果 Markdown版本笔记 我的GitHub首页 我的博客 我的微 ...

  7. http://blog.csdn.net/baidu_31657889/article/details/52315902

    Java技术——你真的了解String类的intern()方法吗 转载 2016年08月25日 16:30:14 标签: java intern / intern / java 技术 6542 0.引 ...

  8. HTML 引用大全

    路径logo <link rel="icon" href="../framework7-4.4.10/kitchen-sink/core/img/ztjs.png& ...

  9. python3对字符串进行base64转码

    import base64# 使用base64的b64encode()进行转码,转码之后在用‘utf-8’解码# s 要转码的字符串res = base64.b64encode(s.encode(&q ...

  10. Mysql之视图和事务(五)

    一:视图 1.问题 对于复杂的查询,往往是有多个数据表进行关联查询而得到,如果数据库因为需求等原因发生了改变,为了保证查询出来的数据与之前相同,则需要在多个地方进行修改,维护起来非常麻烦 解决办法:定 ...