CFP1009F Dominant Indices 学习笔记
CFP1009F Dominant Indices 学习笔记
前言
此处讲长剖优化 DP 做法。因为据说树上启发式合并在这题跑得太慢。
实际上启发式合并那个常数还是很有点肉眼可见的,这题 \(n\) 开到 \(10^6\) 会更明显一些吧……大概。
题意简述
给定一棵 \(n\) 个结点,以 \(1\) 为根的树。定义 \(d(u,x)\) 为 \(u\) 子树中深度为 \(\text{dep}(u)+x\) 的结点数。
对于每个点 \(u\),在保证 \(d(u,k)\) 最大的前提下求最小化 \(k\)。
\(n\le 10^6\)。
做法解析
我们先考虑一个朴素 DP。设 \(f_{u,j}\) 表示 \(u\) 的子树中与 \(u\) 距离为 \(j\) 的点的个数。则有转移方程:\(f_{u,j}=\sum_{v\in \text{son}(u)} f_{v,j-1}\),\(u\) 的答案即为 \(\max f_{u,i}\)。\(ans_u\) 即为满足 \(f_{u,k}=\max f_{u,i}\) 的所有 \(k\) 中的最小值。
但是这坨玩意时空都是 \(O(n^2)\) 的,所以我们需要优化。观察到这玩意在树形态均匀的时候差不多是 \(O(n\log n)\) 的,这启示我们用树剖干掉它,又因为柿子和深度相关,考虑长剖。
长剖优化 DP 究竟是个什么东西?搞懂这题就明白了。
你先考虑一个情景:假如在一条内存空间里我存下了长成这样子的 \(f_v\) 数组:

那么我们会发现,我们往前面再加一格空间,啪的一下,\(f_v\) 数组就以 \(O(1)\) 的代价转移成了 \(f_u\) 数组!
也就是说,我们可以通过合理地分配空间,让 \(f_u\) 的一个儿子 \(O(1)\) 地转移到 \(f_u\),同时其它儿子则不得不暴力合并,感性理解我们应该选择 \(f_u\) 的长儿子这么做。

理性理解,一方面我们发现我们必须选择长儿子这么做,否则 \(f_v\) 的数组装不下长儿子的数组;另一方面这样时空复杂度也有保证:因为每个长链的状态都有且仅有一次被暴力合并(就是在链顶),而长链总长就是 \(O(n)\) 的,所以时间复杂度 \(O(n)\),空间上每个结点只用占一格,所以空间复杂度 \(O(n)\)。
至于这个空间具体怎么分配?遍历出长儿子优先的 dfs 序后,\(u\) 的数组空间始于自己的 \(\text{dfn}\),长度为从自己开始往下的结点数量。
代码实现
哦对了,其实我们并不真的关心 epd[u] 和 dep[u]。我们只关心它们的差值。详见代码。
#include <bits/stdc++.h>
using namespace std;
using namespace obasic;
const int MaxN=1e6+5;
int N,X,Y;
vector<int> Tr[MaxN];
void addudge(int u,int v){
Tr[u].push_back(v);
Tr[v].push_back(u);
}
int edis[MaxN],dson[MaxN];
void dfs1(int u,int f){
for(int v : Tr[u]){
if(v==f)continue;
dfs1(v,u);if(edis[v]>edis[dson[u]])edis[u]=edis[v],dson[u]=v;
}
edis[u]=edis[dson[u]]+1;
}
int pool[MaxN],dfn[MaxN],dcnt,*dp[MaxN],ans[MaxN];
void updans(int u,int x){
int &a=dp[u][ans[u]],&b=dp[u][x];
if(b>a||(b==a&&x<ans[u]))ans[u]=x;
}
void dfs2(int u,int f){
dfn[u]=++dcnt,dp[u]=pool+dfn[u];
dp[u][0]=1;if(!dson[u])return;
dfs2(dson[u],u),updans(u,ans[dson[u]]+1);
for(int v : Tr[u]){
if(v==f||v==dson[u])continue;
dfs2(v,u);for(int i=0;i<edis[v];i++){
dp[u][i+1]+=dp[v][i];
updans(u,i+1);
}
}
}
int main(){
readi(N);
for(int i=1;i<N;i++)readis(X,Y),addudge(X,Y);
dfs1(1,0);dfs2(1,0);
for(int i=1;i<=N;i++)writil(ans[i]);
return 0;
}
浙公网安备 33010602011771号