【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. Autorelease 性能测试

    __weak NSString *string_weak_ = nil; - (void)viewDidLoad { [super viewDidLoad]; // 场景 1 NSString *st ...

  2. VC++获取一个GB级大文件的字节大小

    常规的获得小文件(2.1GB以下)的字节大小可以使用ftell,函数 ftell 用于得到文件位置指针当前位置相对于文件首的偏移字节数.使用fseek函数后再调用函数ftell()就能非常容易地确定文 ...

  3. PHP面试系列之Linux(一) ----- Linux基础

    一.系统安全 sudo:以系统管理者的身份执行指令,也就是说,经由 sudo 所执行的指令就好像是 root 亲自执行. su:用于变更为其他使用者的身份,除 root 外,需要键入该使用者的密码. ...

  4. Dubbo实践(十六)集群容错

    Dubbo作为一个分布式的服务治理框架,提供了集群部署,路由,软负载均衡及容错机制.下图描述了Dubbo调用过程中的对于集群,负载等的调用关系: 集群 Cluster 将Directory中的多个In ...

  5. HDU 1176 免费馅饼 (类似数字三角形的题,很经典,值得仔细理解的dp思维)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1176 免费馅饼 Time Limit: 2000/1000 MS (Java/Others)     ...

  6. sqoop数据迁移

    3.1 概述 sqoop是apache旗下一款“Hadoop和关系数据库服务器之间传送数据”的工具. 导入数据:MySQL,Oracle导入数据到Hadoop的HDFS.HIVE.HBASE等数据存储 ...

  7. CCF认证201803-1 跳一跳

    import java.util.Scanner; public class Jump { public static void main(String[] args) { Scanner sc = ...

  8. [Oracle]记一次由sequence引发的enq sv-contention等待事件

    数据库版本:11.2.0.4 RAC(1)问题现象从EM里面可以看到,在23号早上8:45~8:55时,数据库等待会话暴增,大约到了80个会话.通过查看EM的SQL信息,发现等待产生于SQL语句 se ...

  9. iOS:UITableView相关(18-10-20更)

    UITableView用得较多,遇到的情况也较多,单独记录一篇. 一.零散的技巧 二.取cell 三.cell高度 四.导航栏.TableView常见问题相关 五.自定义左滑删除按钮图片 六.仅做了解 ...

  10. iOS原生分享功能

    iOS_系统原生分享 - CSDN博客 通过UIActivityViewController实现更多分享服务 - 简书 UIActivity - UIKit _ Apple Developer Doc ...