原题链接

\(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. (生鲜项目)08. ModelSerializer 实现商品列表页, 使用Mixin来实现返回, 以及更加方便的ListAPIView, 以及分页的设置

    第一步: 学会使用ModelSerializer, 并且会使用ModelSerializer相互嵌套功能 1. goods.serializers.py from rest_framework imp ...

  2. linux基础命令笔记

    配置IP地址 vi /etc/sysconfig/network-scripts/ifcfg-eth0 忘记root密码grub e 选择kernel按e 输入single b 1:目录及文件的基本操 ...

  3. [转帖]phoronix-test-suite测试云服务器

    phoronix-test-suite测试云服务器 https://www.cnblogs.com/tanyongli/p/7767804.html centos系统 phoronix-test-su ...

  4. [转]Mybatis之TypeHandler使用教程

    Mybatis之TypeHandler使用教程 https://blog.csdn.net/jokemqc/article/details/81326109 深入浅出Mybatis系列(五)---Ty ...

  5. Solr 8.2 使用指南

    1 Solr简介 1.1 Solr是什么 Solr是一个基于全文检索的企业级应用服务器.可以输入一段文字,通过分词检索数据.它是单独的服务,部署在 tomcat. 1.2 为什么需要Solr 问题:我 ...

  6. review代码,需要做些什么???

    有一种习惯,叫看代码找问题:有另一种习惯,叫不看代码很不习惯. 这,矛盾,处处不在! review代码(code diff升级)到底可以做些什么?该做些什么? 1.整体代码风格是否贴切已有框架的设计风 ...

  7. Codeforces Round #590 (Div. 3)补题

    要想上2000分,先刷几百道2000+的题再说 ---某神 题目 E F 赛时是否尝试 × × tag math bitmask 难度 2000 2400 状态 ∅ √ 解 E 待定 F 传送门 第一 ...

  8. linux 从远程服务器拷贝文件

    1.从服务器复制文件到本地: scp root@192.168.1.100:/data/test.txt /home/myfile/ 2.从服务器复制文件夹到本地: scp -r root@192.1 ...

  9. javascript 仿jQuery的无new构造函数

    /* 匿名函数 传入 window 值全局变量成为局部变量 */ (function(window,undefined) { /* 申明一个名为jQuery 的函数*/ function jQuery ...

  10. 怎样在页面关闭时发起HTTP请求

    比如有需求是要让页面关闭时, 在数据库中记录用户的一些数据或log日志. 这时就需要在用户关闭页面时发起HTTP请求. 做法是对window.onunload设置事件监听函数, 在函数内发起AJAX请 ...