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 ...
随机推荐
- CentOS 7 使用unzip解压zip文件提示未找到命令的解决方法
故障现象: 解决方法: 如果你使用unzip命令解压.zip文件,提示未找到命令,可能是你没有安装unzip软件,下面是安装方法 [root@localhost www]# yum install - ...
- Nagios 请检查HTTP服务器关于该CGI的访问权限设置
无权查看任何主机的信息. 请检查HTTP服务器关于该CGI的访问权限设置. 搜索了一下方法 确保 htpasswd.user的所有组为nagios 解决办法: vi /usr/local/nagios ...
- for循环题目记录
1.求1000以内的完数 /** * 一个数如果恰好等于它的因子之和,这个数就是完数,找出1000内的所有完数 * @author 努力Coding * @version * @data */ pub ...
- What's The Next|Kube-OVN 社区线上 Meetup 预告!
Kube-OVN 社区线上Meetup 直播预约通道已开启! 活动时间 2021年8月26日(周四)19:00-20:30 活动介绍 8月26日,Kube-OVN 社区 Meetup 将通过线 ...
- CAS学习笔记五:SpringBoot自动/手动配置方式集成CAS单点登出
本文目标 基于SpringBoot + Maven 分别使用自动配置与手动配置过滤器方式实现CAS客户端登出及单点登出. 本文基于<CAS学习笔记三:SpringBoot自动/手动配置方式集成C ...
- 【失败的经验】在linux下编译opencv for android
cd /home/ahfu#选择opencv 3.4.6版本来编译wget https://github.com/opencv/opencv/archive/3.4.6.tar.gztar -zxvf ...
- Redis作缓存
缓存策略三要素:缓存命中率 缓存更新策略 最大缓存容量.衡量一个缓存方案的好坏标准是:缓存命中率.缓存命中率越高,缓存方法设计的越好. 三者之间的关系为:当缓存到达最大的缓存容量时,会触发缓存更 ...
- JavaScript如何实现上拉加载,下拉刷新?
转载地址: 面试官:JavaScript如何实现上拉加载,下拉刷新? 一.前言 下拉刷新和上拉加载这两种交互方式通常出现在移动端中 本质上等同于PC网页中的分页,只是交互形式不同 开源社区也有很多优秀 ...
- 介绍一个golang库:fastcache
学习VictoriaMetrics源码的时候发现,VictoriaMetrics的缓存部分,使用了同一产品下的fastcache.下面分享阅读fastcache源码的的结论: 1.官方介绍 fastc ...
- python使用pip安装库超时报错解决办法
原因:pip源超时了,安装不上 pip install matplotlib -i http://pypi.douban.com/simple --trusted-host pypi.douban.c ...