【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 其实感觉好像关键是..设一个好的状态?然后..你要用一种十分优秀的方式快乐转移 ...
随机推荐
- Autorelease 性能测试
__weak NSString *string_weak_ = nil; - (void)viewDidLoad { [super viewDidLoad]; // 场景 1 NSString *st ...
- VC++获取一个GB级大文件的字节大小
常规的获得小文件(2.1GB以下)的字节大小可以使用ftell,函数 ftell 用于得到文件位置指针当前位置相对于文件首的偏移字节数.使用fseek函数后再调用函数ftell()就能非常容易地确定文 ...
- PHP面试系列之Linux(一) ----- Linux基础
一.系统安全 sudo:以系统管理者的身份执行指令,也就是说,经由 sudo 所执行的指令就好像是 root 亲自执行. su:用于变更为其他使用者的身份,除 root 外,需要键入该使用者的密码. ...
- Dubbo实践(十六)集群容错
Dubbo作为一个分布式的服务治理框架,提供了集群部署,路由,软负载均衡及容错机制.下图描述了Dubbo调用过程中的对于集群,负载等的调用关系: 集群 Cluster 将Directory中的多个In ...
- HDU 1176 免费馅饼 (类似数字三角形的题,很经典,值得仔细理解的dp思维)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1176 免费馅饼 Time Limit: 2000/1000 MS (Java/Others) ...
- sqoop数据迁移
3.1 概述 sqoop是apache旗下一款“Hadoop和关系数据库服务器之间传送数据”的工具. 导入数据:MySQL,Oracle导入数据到Hadoop的HDFS.HIVE.HBASE等数据存储 ...
- CCF认证201803-1 跳一跳
import java.util.Scanner; public class Jump { public static void main(String[] args) { Scanner sc = ...
- [Oracle]记一次由sequence引发的enq sv-contention等待事件
数据库版本:11.2.0.4 RAC(1)问题现象从EM里面可以看到,在23号早上8:45~8:55时,数据库等待会话暴增,大约到了80个会话.通过查看EM的SQL信息,发现等待产生于SQL语句 se ...
- iOS:UITableView相关(18-10-20更)
UITableView用得较多,遇到的情况也较多,单独记录一篇. 一.零散的技巧 二.取cell 三.cell高度 四.导航栏.TableView常见问题相关 五.自定义左滑删除按钮图片 六.仅做了解 ...
- iOS原生分享功能
iOS_系统原生分享 - CSDN博客 通过UIActivityViewController实现更多分享服务 - 简书 UIActivity - UIKit _ Apple Developer Doc ...