原题链接

\(EDU\)出一道长链剖分优化\(dp\)裸题?

简化版题意

问你每个点的子树中与它距离为多少的点的数量最多,如果有多解,最小化距离

思路

方法1.

用\(dsu\ on\ tree\)做到\(O(nlogn)\)

方法2.

考虑\(dp\),也就是设\(f[u][d]\)表示以\(u\)为根的子树中有多少个点与它的距离为\(j\),则转移如下:

\(f[u][0]=1\),\(f[u][d]+=f[v][d-1]\)

发现可以直接通过把数组右移直接把一个儿子的信息继承过来,又因为转移是跟深度相关的,那么我们直接把长儿子的信息继承过来就好了,然后暴力合并短儿子的信息

这样的时间复杂度都是\(O(n)\)的,怎么证明?直接继承长儿子的信息通过指针可以做到\(O(1)\),然后每条长链只会在顶端被合并,而长链的长度和是\(O(n)\),于是总复杂度就\(O(n)\)啦

空间复杂度的证明同理

代码如下

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <map>
#include <set> using namespace std; #define IINF 0x3f3f3f3f3f3f3f3fLL
#define ull unsigned long long
#define pii pair<int, int>
#define uint unsigned int
#define mii map<int, int>
#define lbd lower_bound
#define ubd upper_bound
#define INF 0x3f3f3f3f
#define vi vector<int>
#define ll long long
#define mp make_pair
#define pb push_back #define N 1000000 struct Edge {
int next, to;
}e[2*N+5]; int n;
int head[N+5], eid, len[N+5], longson[N+5];
int memory[N+5], ans[N+5]; void addEdge(int from, int to) {
e[++eid].next = head[from];
e[eid].to = to;
head[from] = eid;
} void dfs1(int u, int fa) {
for(int i = head[u], v; i; i = e[i].next) {
v = e[i].to;
if(v == fa) continue;
dfs1(v, u);
if(len[longson[u]] < len[v]) longson[u] = v;
}
len[u] = len[longson[u]]+1;
} void dp(int u, int fa, int *f) {
ans[u] = 0;
f[0] = 1;
int *g;
if(longson[u]) {
g = f+1;
dp(longson[u], u, g);
if(g[ans[longson[u]]] > f[ans[u]] || (g[ans[longson[u]]] == f[ans[u]] && ans[longson[u]] < ans[u]))
ans[u] = ans[longson[u]]+1;
}
g = f+len[u];
for(int i = head[u], v; i; i = e[i].next) {
v = e[i].to;
if(v == fa || v == longson[u]) continue;
dp(v, u, g);
for(int j = 1; j <= len[v]; ++j) {
f[j] += g[j-1];
if(f[j] > f[ans[u]] || (f[j] == f[ans[u]] && j < ans[u]))
ans[u] = j;
}
}
} int main() {
scanf("%d", &n);
for(int i = 1, x, y; i < n; ++i) {
scanf("%d%d", &x, &y);
addEdge(x, y), addEdge(y, x);
}
dfs1(1, 0);
dp(1, 0, memory);
for(int i = 1; i <= n; ++i) printf("%d\n", ans[i]);
return 0;
}

CF1009F Dominant Indices——长链剖分优化DP的更多相关文章

  1. CF1009F Dominant Indices 长链剖分

    题目传送门 https://codeforces.com/contest/1009/problem/F 题解 长链剖分的板子吧. 令 \(dp[x][i]\) 表示 \(x\) 的子树中的深度为 \( ...

  2. 【CF1009F】Dominant Indices(长链剖分优化DP)

    点此看题面 大致题意: 设\(d(x,y)\)表示\(x\)子树内到\(x\)距离为\(y\)的点的个数,对于每个\(x\),求满足\(d(x,y)\)最大的最小的\(y\). 暴力\(DP\) 首先 ...

  3. 2019.01.19 bzoj3653: 谈笑风生(长链剖分优化dp)

    传送门 长链剖分优化dpdpdp水题. 题意简述:给一棵树,mmm次询问,每次给一个点aaa和一个值kkk,询问满足如下条件的三元组(a,b,c)(a,b,c)(a,b,c)的个数. a,b是c的祖先 ...

  4. 长链剖分优化dp三例题

    首先,重链剖分我们有所认识,在dsu on tree和数据结构维护链时我们都用过他的性质. 在这里,我们要介绍一种新的剖分方式,我们求出这个点到子树中的最长链长,这个链长最终从哪个儿子更新而来,那个儿 ...

  5. Codeforces 1009 F. Dominant Indices(长链剖分/树上启发式合并)

    F. Dominant Indices 题意: 给一颗无向树,根为1.对于每个节点,求其子树中,哪个距离下的节点数量最多.数量相同时,取较小的那个距离. 题目: 这类题一般的做法是树上的启发式合并,复 ...

  6. CF 1009 F Dominant Indices —— 长链剖分+指针

    题目:http://codeforces.com/contest/1009/problem/F 也可以用 dsu on tree 的做法,全局记录一个 dep,然后放进堆里,因为字典序要最小,所以再记 ...

  7. 2018.11.03 NOIP模拟 树(长链剖分优化dp)

    传送门 考虑直接推式子不用优化怎么做. 显然每一个二进制位分开计算贡献就行. 即记录fi,jf_{i,j}fi,j​表示距离iii这个点不超过jjj的点的每个二进制位的0/10/10/1个数. 但直接 ...

  8. BZOJ4543[POI2014]Hotel加强版——长链剖分+树形DP

    题意参见BZOJ3522 n<=100000 数据范围增强了,显然之前的转移方程不行了,那么不妨换一种. 因为不能枚举根来换根DP,那么我们描述的DP方程每个点要计算三个点都在这个点的子树内的方 ...

  9. 长链剖分优化树形DP总结

    长链剖分 规定若\(x\)为叶结点,则\(len[x]=1\). 否则定义\(preferredchild[x]\)(以下简称\(pc[x]\),称\(pc[x]\)为\(x\)的长儿子)为\(x\) ...

随机推荐

  1. NDK学习笔记-使用现有so动态库

    前面将的都是如何使用C/C++文件生成so动态库,那么在使用别人的so动态库的时候应该怎么做呢?这篇文章就是使用一个变声功能的动态库,完成对于以有so动态库的说明. 动态库来源 在互联网中,有着许许多 ...

  2. [转帖]phoronix-test-suite 简介

    <工作杂记>之phoronix-test-suite 2017年10月30日 14:32:52 打雷下雨 阅读数 2078更多 分类专栏: # linux   版权声明:本文为博主原创文章 ...

  3. (八)Spring 事务管理

    目录 文章目录 @[toc] **`Spring`** 事务管理 `Api` 介绍之 **`PlatformTransactionManager`** 后记 #Spring 的事务管理 编程式事务管理 ...

  4. HDU - 2196(树形DP)

    题目: A school bought the first computer some time ago(so this computer's id is 1). During the recent ...

  5. Prometheus Operator 的安装

    Prometheus Operator 的安装 接下来我们用自定义的方式来对 Kubernetes 集群进行监控,但是还是有一些缺陷,比如 Prometheus.AlertManager 这些组件服务 ...

  6. 代理模式与动态代理之JDK实现和CGlib实现

    静态代理 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类. 由业务实现类.业务代理类 两部分组成.业务实现类 负责实现主要的业务方法,业务代理类负责对调用的业务方法作拦截.过滤.预处理, ...

  7. LocalDate与Date转化

    // 01. java.util.Date --> java.time.LocalDateTimepublic void UDateToLocalDateTime() { java.util.D ...

  8. MyBatis 源码篇-插件模块

    本章主要描述 MyBatis 插件模块的原理,从以下两点出发: MyBatis 是如何加载插件配置的? MyBatis 是如何实现用户使用自定义拦截器对 SQL 语句执行过程中的某一点进行拦截的? 示 ...

  9. oracle学习笔记03

    一:表空间 /* 创建表空间:逻辑单位,通常我们新建一个项目,就会去创建表空间,在表空间中创建用户,用户去创建表. 语法:create tablespace 表空间名字 datafile '文件的路径 ...

  10. 阿里云 负载均衡 HTTP转HTTPS

    一.相关文档 1.证书服务 2.简单路由-HTTP 协议变为 HTTPS 协议 二.阿里云操作界面 1.云盾证书服务管理控制台(查询CA证书服务) 2.负载均衡管理控制台 三.相关文档 1.Syman ...