题面

$\text{BZOJ}$间接权限题

洛谷的弱化版

题解

三点距离两两相等要满足以下条件:

有一个相同的$\text{LCA}$

所以如果存在一个点,使得另外两个点在它子树中,距离为$d$,且$\text{LCA}$距这个点为$d$,

那么这三个点就距离两两相等。

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

$g[i][j]$表示以$i$为根的子树中,两个点到$LCA$的距离为$d$,并且他们的$LCA$到$i$的距离为$d−j$的点对数。

看到合并时的转移:

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

复杂度为$\text{O}(n^2)$

而转移方程下面两个柿子

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

如果我们选择一个转移代价最高的儿子直接继承过来的话,复杂度就会大大降低

而转移代价最高的儿子显然就是长链剖分后那个点的重儿子

那么用指针描述就是:

$$ f[i]=f[heavy[i]] - 1,\; g[i] = g[heavy[i]] + 1 $$

这样可以快速继承。

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

于是从重儿子转移$O(1)$,从轻儿子转移$O($链长$)$

总时间复杂度$O(n+\sum$链长$)=O(n)$

同时因为使用指针,所以常数小出现了一些玄学问题

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define RG register inline int read()
{
int data = 0, w = 1;
char ch = getchar();
while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if(ch == '-') w = -1, ch = getchar();
while(ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
return data * w;
} const int maxn(100010);
struct edge { int next, to; } e[maxn << 1];
int head[maxn], e_num, n;
inline void add_edge(int from, int to)
{
e[++e_num] = (edge) {head[from], to};
head[from] = e_num;
} int dep[maxn], heavy[maxn], maxdep[maxn];
void dfs(int x, int fa)
{
// maxdep[x] = dep[x] = dep[fa] + 1;
for(RG int i = head[x]; i; i = e[i].next)
{
int to = e[i].to; if(to == fa) continue;
dfs(to, x); maxdep[x] = std::max(maxdep[x], maxdep[to]);
if(maxdep[to] > maxdep[heavy[x]]) heavy[x] = to;
}
maxdep[x] = maxdep[heavy[x]] + 1;
// 玄学问题,将第28行注释去掉并注释掉上一行,交到BZOJ就会RE
} long long *f[maxn], *g[maxn], pool[maxn << 2], *id = pool, ans;
void calc(int x, int fa)
{
if(heavy[x]) f[heavy[x]] = f[x] + 1,
g[heavy[x]] = g[x] - 1, calc(heavy[x], x);
f[x][0] = 1, ans += g[x][0];
for(RG int i = head[x]; i; i = e[i].next)
{
int to = e[i].to; if(to == fa || to == heavy[x]) continue;
f[to] = id; id += maxdep[to] << 1; g[to] = id; id += maxdep[to] << 1;
calc(to, x);
for(RG int j = 0; j < maxdep[to]; j++)
{
if(j) ans += f[x][j - 1] * g[to][j];
ans += g[x][j + 1] * f[to][j];
}
for(RG int j = 0; j < maxdep[to]; j++)
{
g[x][j + 1] += f[x][j + 1] * f[to][j];
if(j) g[x][j - 1] += g[to][j];
f[x][j + 1] += f[to][j];
}
}
} int main()
{
n = read();
for(RG int i = 1, a, b; i < n; i++)
a = read(), b = read(), add_edge(a, b), add_edge(b, a);
dfs(1, 0); f[1] = id; id += maxdep[1] << 1; g[1] = id; id += maxdep[1] << 1;
calc(1, 0); printf("%lld\n", ans);
return 0;
}

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

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

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

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

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

  3. 【BZOJ4543】Hotel加强版

    [BZOJ4543]Hotel加强版 题面 bzoj 洛谷 $ps:$在洛谷看题在bzoj交... 题解 我们分析一下这个问题,要怎么样的点才满足三点距离两两相等呢? 1.存在三个点有共同的$LCA$ ...

  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. ASP.NET MVC 5搭建自己的视图基架 (CodeTemplate)

    我们知道,在MVC项目中添加视图时,在添加面板有模板可以选择,这里会有人疑问,这个模板位于哪里?我可以搭建自己的基架吗? 首先回答第二个问题,答案是当然可以 我这里使用的是Visual Studio ...

  2. Oracle 客户端库时引发 BadImageFormatException

    程序提示错误: 试加载 Oracle 客户端库时引发 BadImageFormatException.如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题. 出现场 ...

  3. 一些centos 6和centos 7的区别

      CentOS 6(OLE 6,RHEL 6类似) CcnetOS 7(OLE 7,RHEL 7类似) 影响 默认文件系统 ext4 xfs 大量小文件在ext4上工作性能较好在64位linux中, ...

  4. Linux FFmpeg(含x264、lame插件)安装记录

    What is FFmpeg? FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.它提供了录制.转换以及流化音视频的完整解决方案. What is x264? H. ...

  5. CSS学习摘要-定位实例

    CSS学习摘要-定位实例 注:全文摘自MDN-CSS定位实例 列表消息盒子 我们研究的第一个例子是一个经典的选项卡消息框,你想用一块小区域包括大量信息时,一个非常常用的特征.这包括含有大信息量的应用, ...

  6. UNIX日期与时间

    日期和时间 UINX系统内部有一个变量记录自开机以来经过的时间.从用户的角度,UNIX时间函数分为3类: 度量进程已使用CPU时间的函数: 给出绝对时间或日历时间的函数: 设置闹钟.定时器以及睡眠的函 ...

  7. 第一篇,编译生成libcef_dll_wrapper

    因为工作原因需要在程序里面嵌入地图,在网上看了百度地图和高德地图都没有提供c++的接口,提供有web接口,那只好在程序里面嵌入web控件了,第一想到的是web browser控件,接着脑海里又想到IE ...

  8. 洛谷 P2764 最小路径覆盖问题【最大流+拆点+路径输出】

    题目链接:https://www.luogu.org/problemnew/show/P2764 题目描述 «问题描述: 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V ...

  9. ueditor 百度编辑器 解决表格没有边框

    因为项目需要,发现直接从word和excel复制粘贴以后,居然在禅道上表格没有边框了,故查了一下 这里从word,以及excel粘贴复制,都能直接有边框了,同时在编辑器里面新增表格,也能直接显示边框了 ...

  10. 【AT987】高橋君

    题目 成爷爷一眼秒,\(tql!!!\) 多组询问,求 \[\sum_{i=0}^kC_{n}^i \] 发现\(k<=n\)啊,于是我们可以把一组询问抽象成一个区间\([k,n]\) 左指针的 ...