Solution -「POI 2014」「洛谷 P5904」HOT-Hotels 加强版
\(\mathcal{Description}\)
Link.
给定一棵 \(n\) 个点的树,求无序三元组 \((u,v,w)\) 的个数,满足其中任意两点树上距离相等。
\(n\le10^5\)。
\(\mathcal{Solution}\)
考虑如何计数。对于任意三元组 \((u,v,w)\),我们仅在其两两路径所进过的树上最高点对其统计一次。如图:

对于三元组 \((4,6,7)\),我们仅希望在 \(1\) 处统计它的贡献。
考虑 DP,记 \(d(u,v)\) 表示 \(u\) 到 \(v\) 的树上距离。令 \(f(u,i)\) 表示 \(u\) 子树内 \(v\) 的个数,满足 \(d(u,v)=i\);\(g(u,i)\) 表示 \(u\) 子树内无序二元组 \((p,q)\) 的个数,满足 \(d(p,\operatorname{lca}(p,q))=d(q,\operatorname{lca}(p,q))=d(\operatorname{lca}(p,q),u)+i\)。例如上图的 \(g(2,2)=1\),无序二元组 \((4,6)\) 满足条件。
如此设计状态的意义在于,在 \(g(u,i)\) 的基础上,在 \(u\) 子树的外部接上一个满足 \(d(u,w)=i\) 的 \(w\) 就能构成三元组,并且三元组恰好在最高点 \(u\) 计数。
暴力转移比较显然,发现状态的第二维的范围均为 \(u\) 向下的最长链长,所以用长链剖分优化,直接移动指针继承 \(\mathcal O(1)\) 继承长儿子信息,做到均摊 \(\mathcal O(n)\) 转移,故总复杂度 \(\mathcal O(n)\)。
\(\mathcal{Code}\)
#include <cstdio>
#define alloc( u ) \
( f[u] = cur, g[u] = ( cur += dep[u] << 1 ), cur += dep[u] << 1 )
typedef long long LL;
const int MAXN = 1e5;
int n, ecnt, head[MAXN + 5];
int dep[MAXN + 5], son[MAXN + 5];
LL ans, *f[MAXN + 5], *g[MAXN + 5], pool[MAXN * 5], *cur = pool;
struct Edge { int to, nxt; } graph[MAXN * 2 + 5];
inline void link ( const int s, const int t ) {
graph[++ ecnt] = { t, head[s] };
head[s] = ecnt;
}
inline void init ( const int u, const int fa ) {
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( ( v = graph[i].to ) ^ fa ) {
init ( v, u );
if ( dep[v] > dep[son[u]] ) son[u] = v;
}
}
dep[u] = dep[son[u]] + 1;
}
inline void solve ( const int u, const int fa ) {
if ( son[u] ) {
f[son[u]] = f[u] + 1, g[son[u]] = g[u] - 1;
solve ( son[u], u );
}
f[u][0] = 1, ans += g[u][0];
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( ( v = graph[i].to ) ^ fa && v ^ son[u] ) {
alloc ( v ), solve ( v, u );
for ( int j = 0; j < dep[v]; ++ j ) {
if ( j ) ans += f[u][j - 1] * g[v][j];
ans += g[u][j + 1] * f[v][j];
}
for ( int j = 0; j < dep[v]; ++ j ) {
g[u][j + 1] += f[u][j + 1] * f[v][j];
if ( j ) g[u][j - 1] += g[v][j];
f[u][j + 1] += f[v][j];
}
}
}
}
int main () {
scanf ( "%d", &n );
for ( int i = 1, u, v; i < n; ++ i ) {
scanf ( "%d %d", &u, &v );
link ( u, v ), link ( v, u );
}
init ( 1, 0 );
alloc ( 1 );
solve ( 1, 0 );
printf ( "%lld\n", ans );
return 0;
}
Solution -「POI 2014」「洛谷 P5904」HOT-Hotels 加强版的更多相关文章
- 「区间DP」「洛谷P1043」数字游戏
「洛谷P1043」数字游戏 日后再写 代码 /*#!/bin/sh dir=$GEDIT_CURRENT_DOCUMENT_DIR name=$GEDIT_CURRENT_DOCUMENT_NAME ...
- 洛谷P1120 小木棍 [数据加强版](搜索)
洛谷P1120 小木棍 [数据加强版] 搜索+剪枝 [剪枝操作]:若某组拼接不成立,且此时 已拼接的长度为0 或 当前已拼接的长度与刚才枚举的长度之和为最终枚举的答案时,则可直接跳出循环.因为此时继续 ...
- Solution -「POI 2010」「洛谷 P3511」MOS-Bridges
\(\mathcal{Description}\) Link.(洛谷上这翻译真的一言难尽呐. 给定一个 \(n\) 个点 \(m\) 条边的无向图,一条边 \((u,v,a,b)\) 表示从 ...
- Solution -「JSOI 2019」「洛谷 P5334」节日庆典
\(\mathscr{Description}\) Link. 给定字符串 \(S\),求 \(S\) 的每个前缀的最小表示法起始下标(若有多个,取最小的). \(|S|\le3\time ...
- Solution -「洛谷 P4372」Out of Sorts P
\(\mathcal{Description}\) OurOJ & 洛谷 P4372(几乎一致) 设计一个排序算法,设现在对 \(\{a_n\}\) 中 \([l,r]\) 内的元素排 ...
- Solution -「APIO 2016」「洛谷 P3643」划艇
\(\mathcal{Description}\) Link & 双倍经验. 给定 \(n\) 个区间 \([a_i,b_i)\)(注意原题是闭区间,这里只为方便后文描述),求 \(\ ...
- 「洛谷4197」「BZOJ3545」peak【线段树合并】
题目链接 [洛谷] [BZOJ]没有权限号嘤嘤嘤.题号:3545 题解 窝不会克鲁斯卡尔重构树怎么办??? 可以离线乱搞. 我们将所有的操作全都存下来. 为了解决小于等于\(x\)的操作,那么我们按照 ...
- 「洛谷3338」「ZJOI2014」力【FFT】
题目链接 [BZOJ] [洛谷] 题解 首先我们需要对这个式子进行化简,否则对着这么大一坨东西只能暴力... \[F_i=\sum_{j<i} \frac{q_iq_j}{(i-j)^2}-\s ...
- 「BZOJ2733」「洛谷3224」「HNOI2012」永无乡【线段树合并】
题目链接 [洛谷] 题解 很明显是要用线段树合并的. 对于当前的每一个连通块都建立一个权值线段树. 权值线段树处理操作中的\(k\)大的问题. 如果需要合并,那么就线段树暴力合并,时间复杂度是\(nl ...
随机推荐
- vscode 前端好用插件汇总
本篇文章根据实际开发中使用的扩展插件,结合<精选!15 个必备的 VSCode 插件(前端类)>.<vscode 插件推荐 - 献给所有前端工程师(2017.8.18更新)>中 ...
- javascript中什么时候要用\来转义
1.定义字符串的单引号或双引号里的同符号或字符串内回车换行,比如A: a = "<a href=\"...\">a</a>"; B: a ...
- JAVA-JDK1.7-ConCurrentHashMap-测试和验证
概述 上次记录了关于ConCurrentHashMap的原理以及源码,现在我对其进行有关功能的测试,下面就讲解一下我测试的内容和代码.这些测试主要针对JDK1.7版本. GET安全测试 上一篇写过ge ...
- Scala语言介绍一
为什么学习scala语言 Scala是基于JVM的语言,与java语言类似,java语言是基于JVM的面向对象的语言,Scala也是基于JVM,同时支持面向对象和面向函数的编程语言.Spark底层的源 ...
- 服务器表单字符串转化Vue表单挂在到对应DOM节点
今天在项目开发中,遇到从后端返回的vue文件(包含template,js,css)的文件,试过用v-html解析文件,渲染到页面,但是无法渲染,后来去查了一堆资料,自己写了一个全局方法来解析这类文件 ...
- vue3路由的使用,保证你有所收获!
路由变量 有的小伙伴,可能是第一次听见路由变量这个词. 什么是路由变量了,顾名思义就是这个路由地址是动态的,不是固定的. 它的运用场景是哪里呢? 比如说:1.详情页的地址,我们就可以去使用路由变量. ...
- echarts x轴的纵向区域随便点击获取点击的x轴那一纵向区域的值
1.现在xAxis里面配置一下: 2.在生成图表的后面加入框起来的部分 myChart.getZr().on('click', function (params) { /* 通过获取echarts上面 ...
- 利用SelectPdf插件将网页生成PDF
简介 适用于.NET Framework和.NET Core的HTML至PDF转换器 SelectPdf提供的在线html到pdf转换器使用.NET的Select.Pdf库中的html到pdf转换器. ...
- 集合框架-工具类-JDK5.0特性-函数可变参数
1 package cn.itcast.p4.news.demo; 2 3 public class ParamterDemo { 4 5 public static void main(String ...
- keepalived的抢占与非抢占模式
目录 一:keepalived的抢占与非抢占模式 1.抢占模式 2.非抢占模式 二:接下来分4种情况说明 三:以上3种,只要级别高就会获取master,与state状态是无关的 一:keepalive ...