【BZOJ4543】Hotel加强版
【BZOJ4543】Hotel加强版
题面
$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加强版的更多相关文章
- BZOJ4543 Hotel加强版
题面 $\text{BZOJ}$间接权限题 洛谷的弱化版 题解 三点距离两两相等要满足以下条件: 有一个相同的$\text{LCA}$ 所以如果存在一个点,使得另外两个点在它子树中,距离为$d$,且$ ...
- BZOJ4543 Hotel加强版(长链剖分)
题意 求一棵树上,两两距离相等的三个点的三元组(无序)的个数. 题解 转自 CaptainHarryChen 的博客 CODE 代码中的f,gf,gf,g对应题解中的num,waynum,waynum ...
- 【BZOJ4543】Hotel加强版(长链剖分)
[BZOJ4543]Hotel加强版(长链剖分) 题面 BZOJ,没有题面 洛谷,只是普通版本 题解 原来我们的\(O(n^2)\)做法是设\(f[i][j]\)表示以\(i\)为根的子树中,距离\( ...
- 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 ...
- BZOJ4543 [POI2014]Hotel加强版
题意 有一个树形结构,每条边的长度相同,任意两个节点可以相互到达.选3个点.两两距离相等.有多少种方案? 数据范围:n<=100000 分析 参照小蒟蒻yyb的博客. 我们先考虑一个\(O(n^ ...
- 【BZOJ4543】[POI2014]Hotel加强版 长链剖分+DP
[BZOJ4543][POI2014]Hotel加强版 Description 同OJ3522数据范围:n<=100000 Sample Input 7 1 2 5 7 2 5 2 3 5 6 ...
- 4543: [POI2014]Hotel加强版
4543: [POI2014]Hotel加强版 链接 分析: f[u][i]表示子树u内,距离u为i的点的个数,g[u][i]表示在子树u内,已经选了两个深度一样的点,还需要在距离u为i的一个点作为第 ...
- 蒟蒻的长链剖分学习笔记(例题:HOTEL加强版、重建计划)
长链剖分学习笔记 说到树的链剖,大多数人都会首先想到重链剖分.的确,目前重链剖分在OI中有更加多样化的应用,但它大多时候是替代不了长链剖分的. 重链剖分是把size最大的儿子当成重儿子,顾名思义长链剖 ...
- 【bzoj4543】Hotel加强版(thr)
Portal --> bzoj4543 Solution 一年前的题== 然而一年前我大概是在划水qwq 其实感觉好像关键是..设一个好的状态?然后..你要用一种十分优秀的方式快乐转移 ...
随机推荐
- python的*args和**kwargs基础用法
*args表示任何多个无名参数,它是一个tuple **kwargs:传入的字典,就如:a=1,传入键值,默认就传入到**kwargs中,如下面代码: class FOO: def __init__( ...
- BZOJ 1491 社交网络 Floyd 最短路的数目
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1491 题目大意: 见链接 思路: 直接用floyd算法求最短路,同时更新最短路的数目即 ...
- Unable to perform unmarshalling at line number 16 and column 63 in RESOURCE hibernate.cfg.xml. Message: cvc-elt.1: 找不到元素 'hibernate-configuration' 的声明。
七月 02, 2017 4:32:37 下午 org.hibernate.Version logVersionINFO: HHH000412: Hibernate Core {5.2.10.Final ...
- java反序列化Commons-Collections1分析
AnnotationInvocationHandler关键类 Commons-Collections1也是利用InvokerTransformer类中的transform方法反射机制执行命令.实验用的 ...
- WEB安全 Sqlmap 中绕过空格拦截的12个脚本
图片较小,可以右键点击图片-->选择 "在新标签中打开图片" --> 查看大图 Sql 注入时遇到过滤空格时可以使用下面12个脚本尝试绕过,在实际利用中可以灵活修改.
- Spring(十一)之AOP
Spring 框架的一个关键组件是面向方面的编程(AOP)框架.面向方面的编程需要把程序逻辑分解成不同的部分称为所谓的关注点.跨一个应用程序的多个点的功能被称为横切关注点,这些横切关注点在概念上独立于 ...
- ubuntu使用----高效快捷键
桌面快捷键 : ALT + F1: 聚焦到桌面左侧任务导航栏,可按上下键导航. ALT + F2: 运行命令 ALT + F4: 关闭窗口 ALT + TAB: 切换程序窗口 ALT + 空格: 打开 ...
- 优化Eclipse基本配置
eclipse有很多默认配置会造成其本身运行缓慢,特别是加载大型工程的时候,以下列举的几种方法可以优化eclipse的运行速度,加快工程的加载和构建. 关闭XML Validation 1. 关闭当前 ...
- python - 流程控制基础习题
#打印1 到100 的和** i = 0 s = 0 while i <100: i += 1 s += i print(s) print('1+2+,,100=',s) #打印字符A~Z fo ...
- HTML5视频播放练习:鼠标经过视频播放,鼠标移除停止播放,再次经过继续播放。
随着HTML5的广泛应用,在一些网站中,经常看到有些预览的短视频预览,鼠标经过就会播放,移除就会停止播放,再次移进去就会继续播放. 自己也研究着做一个比较简单的类似的练习. 视频可以自己到包图网下载, ...