【BZOJ4543】Hotel加强版

题面

bzoj

洛谷

$ps:$在洛谷看题在bzoj交。。。

题解

我们分析一下这个问题,要怎么样的点才满足三点距离两两相等呢?

1、存在三个点有共同的$LCA$。

2、存在一个点,使得它到它两颗不同的子树种两点的距离为$d$且它存在$d$级祖先。

考虑$dp:$

设$f[i][j]$表示以$i$为根的子树中,距离$i$为$j$的点数

$g[i][j]$表示以$i$为根的子树中两点到$LCA$距离为$d$,并且它们$LCA$到$j$的距离为$d$的节点数

合并信息时进行转移:

$$ ans+=g[i][0]\\ ans+=g[i][j]*f[son][j-1]\\ f[i][j]+=f[son][j-1]\\ g[i][j]+=g[son][j+1] $$

现在复杂度$O(n^2)$ 注意到这两个式子

$$ f[i][j]+=f[son][j-1]\\ g[i][j]+=g[son][j+1] $$

如果我们钦定一个儿子,就不需要再进行重复计算了

我们用指针来描述

$$ f[i]=f[son]-1,g[i]=g[son]+1 $$

发现链上转移是$O(n)$的

于是我们在树上做这个事情。

将整棵树进行长链剖分,钦定从重儿子转移,其他儿子重新计算

是不是和$dsu\;on\;tree$特别像?

那这样的话,从重儿子转移$O(1)$,从轻儿子转移$O(链长)$

这样总复杂度$O(n)$

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
inline int gi() {
register int data = 0, w = 1;
register char ch = 0;
while (!isdigit(ch) && ch != '-') ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar();
return w * data;
}
typedef long long ll;
const int MAX_N = 1e5 + 5;
struct Graph { int to, next; } e[MAX_N << 1]; int fir[MAX_N], e_cnt = 0;
void clearGraph() { memset(fir, -1, sizeof(fir)); e_cnt = 0; }
void Add_Edge(int u, int v) { e[e_cnt] = (Graph){v, fir[u]}; fir[u] = e_cnt++; }
int N, dep[MAX_N], son[MAX_N], md[MAX_N];
void dfs1(int x, int fa) {
//md[x] = dep[x] = dep[fa] + 1;
for (int i = fir[x]; ~i; i = e[i].next) {
int v = e[i].to; if (v == fa) continue;
dfs1(v, x);
if (md[v] > md[son[x]]) son[x] = v, md[x] = md[v];
}
md[x] = md[son[x]] + 1;
}
ll *f[MAX_N], *g[MAX_N], tmp[MAX_N << 2], *pos = tmp, ans;
void dfs(int x, int fa) {
if (son[x]) f[son[x]] = f[x] + 1, g[son[x]] = g[x] - 1, dfs(son[x], x);
f[x][0] = 1, ans += g[x][0];
for (int i = fir[x]; ~i; i = e[i].next) {
int v = e[i].to; if (v == fa || v == son[x]) continue;
f[v] = pos, pos += md[v] << 1, g[v] = pos, pos += md[v] << 1;
dfs(v, x);
for (int j = 0; j < md[v]; j++) {
if (j) ans += f[x][j - 1] * g[v][j];
ans += g[x][j + 1] * f[v][j];
}
for (int j = 0; j < md[v]; j++) {
g[x][j + 1] += f[x][j + 1] * f[v][j];
if (j) g[x][j - 1] += g[v][j];
f[x][j + 1] += f[v][j];
}
}
}
int main () {
clearGraph();
N = gi();
for (int i = 1; i < N; i++) {
int u = gi(), v = gi();
Add_Edge(u, v), Add_Edge(v, u);
}
dfs1(1, 0); f[1] = pos, pos += md[1] << 1, g[1] = pos, pos += md[1] << 1;
dfs(1, 0);
printf("%lld\n", ans);
return 0;
}

玄学问题:去掉第$23$行注释,并注释调第$29$行会$RE$

【BZOJ4543】Hotel加强版的更多相关文章

  1. BZOJ4543 Hotel加强版

    题面 $\text{BZOJ}$间接权限题 洛谷的弱化版 题解 三点距离两两相等要满足以下条件: 有一个相同的$\text{LCA}$ 所以如果存在一个点,使得另外两个点在它子树中,距离为$d$,且$ ...

  2. BZOJ4543 Hotel加强版(长链剖分)

    题意 求一棵树上,两两距离相等的三个点的三元组(无序)的个数. 题解 转自 CaptainHarryChen 的博客 CODE 代码中的f,gf,gf,g对应题解中的num,waynum,waynum ...

  3. 【BZOJ4543】Hotel加强版(长链剖分)

    [BZOJ4543]Hotel加强版(长链剖分) 题面 BZOJ,没有题面 洛谷,只是普通版本 题解 原来我们的\(O(n^2)\)做法是设\(f[i][j]\)表示以\(i\)为根的子树中,距离\( ...

  4. BZOJ4543 POI2014 Hotel加强版 【长链剖分】【DP】*

    BZOJ4543 POI2014 Hotel加强版 Description 同OJ3522 数据范围:n<=100000 Sample Input 7 1 2 5 7 2 5 2 3 5 6 4 ...

  5. BZOJ4543 [POI2014]Hotel加强版

    题意 有一个树形结构,每条边的长度相同,任意两个节点可以相互到达.选3个点.两两距离相等.有多少种方案? 数据范围:n<=100000 分析 参照小蒟蒻yyb的博客. 我们先考虑一个\(O(n^ ...

  6. 【BZOJ4543】[POI2014]Hotel加强版 长链剖分+DP

    [BZOJ4543][POI2014]Hotel加强版 Description 同OJ3522数据范围:n<=100000 Sample Input 7 1 2 5 7 2 5 2 3 5 6 ...

  7. 4543: [POI2014]Hotel加强版

    4543: [POI2014]Hotel加强版 链接 分析: f[u][i]表示子树u内,距离u为i的点的个数,g[u][i]表示在子树u内,已经选了两个深度一样的点,还需要在距离u为i的一个点作为第 ...

  8. 蒟蒻的长链剖分学习笔记(例题:HOTEL加强版、重建计划)

    长链剖分学习笔记 说到树的链剖,大多数人都会首先想到重链剖分.的确,目前重链剖分在OI中有更加多样化的应用,但它大多时候是替代不了长链剖分的. 重链剖分是把size最大的儿子当成重儿子,顾名思义长链剖 ...

  9. 【bzoj4543】Hotel加强版(thr)

    Portal --> bzoj4543 Solution ​ 一年前的题== 然而一年前我大概是在划水qwq ​​ 其实感觉好像关键是..设一个好的状态?然后..你要用一种十分优秀的方式快乐转移 ...

随机推荐

  1. jQuery UI 实例 – 切换(Toggle)

    toggle()函数用于为每个匹配元素的click事件绑定轮流的处理函数. toggle()是一个特殊的事件函数,用于为匹配元素的click事件绑定多个事件处理函数.每次触发click事件时,togg ...

  2. 使用loader打包静态文件-样式2

    这篇我们了解下css-loader常用的配置项,要配置的话,use里面就不再是一个字符串了 // 打包模块不知道该怎么办,就去模块配置里面该怎么办 module: { // 规则 rules: [{ ...

  3. virtualbox+vagrant学习-4-Vagrantfile-3-Minimum Vagrant Version

    Minimum Vagrant Version 可以在Vagrantfile中指定一组vagrant版本需求,以强制人们使用带有Vagrantfile文件的vagrant特定版本.这可以帮助解决使用带 ...

  4. 【51nod 1685】 第K大区间2

    题目描述: 定义一个长度为奇数的区间的值为其所包含的的元素的中位数.现给出n个数,求将所有长度为奇数的区间的值排序后,第K大的值为多少. 样例解释: [l,r]表示区间的值 [1]:3 [2]:1 [ ...

  5. 基于MySql数据库的单表与多表联合查询

    这里以学生 班级 身份证 以及课程为例 1,启动MySql数据库  开启服务 2.1.0新建一张班级表 备注:CHARSET = UTF8 (指定编码格式为utf8 防止中文乱码) /*班级表*/ C ...

  6. ext4文件系统特性浅析

    ext4作为Linux下的文件系统因其简单性.易管理性.兼容性强等特定,深受大多数用户喜欢,并且作为大多数Linux发行版中的默认文件系统.但是随着现在文件数目的增多以及文件数据的增大,ext4文件系 ...

  7. JavaScript前端将时间戳转换为日期格式

    function (data) { var date = new Date(data) var Y = date.getFullYear() + '-' var M = (date.getMonth( ...

  8. 用HTML编写漫威页面

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  9. mysql数据库锁简介

    本篇介绍有关数据库锁相关的知识,关于数据库事务及隔离级别参见<数据库事务ACID特性及隔离级别>这篇文.   乐观锁 乐观锁最常用的实现方式是用数据版本(Version)记录机制.数据版本 ...

  10. 在VSCode使用Markdown绘制UML图

    在VSCode使用Markdown绘制UML图 需要插件 Markdown All in One Markdown Preview Enhanced PlantUML markdownlint Mar ...