题面

$\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. 分别用C/C++ 和 C#实现简单的观察者模式

    网上找了很多关于观察者模式的代码例子和文章,都写的比较复杂,我个人还是喜欢从易到难,今天自己参考网上资料,也写了一个简单观察者模式的例子,简单的复习了一下Observer 模式,Observer 模式 ...

  2. Linux 下 python如何配置virtualenv

    .安装virtualenv pip3 install virtualenv pip install -i https://pypi.tuna.tsinghua.edu.cn/simple virtua ...

  3. (z转)基于CPU的Bank BRDF经验模型,实现各向异性光照效果!

    摘抄“GPU Programming And Cg Language Primer 1rd Edition” 中文 名“GPU编程与CG语言之阳春白雪下里巴人” BRDF 光照模型 10.2.1 什么 ...

  4. springmvc处理日期格式

    解决http400错误 通常有两个来源: 1 页面的下拉列表中传入了字符串,而服务器需要的是Integer类型的,所以服务器拒绝. 2, 浏览器传给服务器端的日期格式字符串,服务器端理解不了,所以需要 ...

  5. zabbix日常监控项java(四又分之一)

    因zabbix自带监控JMX的模板通用性差的问题,需要我们自己新建一个属于自己的模板,于是本文就出现了.... 大部分都是参考网上其他博主的文档,在此作为梳理.总结:以方便自己日后使用查询.

  6. Gsoap在QT工程里如何调用

    Qt并没有SOAP的官方实现,都是借助三方库来实现,不过似乎有个QtSoap,不过这个不是太会用,所以还是用Gsoap 这里生成纯C文件, 1.下载gSOAP(http://sourceforge.n ...

  7. Java基础面试题(进程和线程的区别)

    进程和线程的区别 1.定义 进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程:进程的一个实体,是CPU调度和分派的基本单位,它是比进程更 ...

  8. SGU---101 无向图的欧拉回路

    题目链接: https://cn.vjudge.net/problem/SGU-101 题目大意: 给定你n张骨牌,每张牌左右两端有一个数字,每张牌的左右两端数字可以颠倒,找出一种摆放骨牌的顺序,使得 ...

  9. tomcat 开启远程debug

    修改 tomcat  目录下  /bin/catelina.sh #                   execution immediately after startup. Default is ...

  10. CSS3新特性2D、3D效果讲解

    希望这篇博客可以对你有所帮助,如果有什么技术上的问题,希望我们可以做进一步的交流,如果你觉得我哪里阐述的不正确或者你有更好的更透彻的理解,也可以联系我,我在这里随时等着你. 对于css/html是每个 ...