Codeforces 442D Adam and Tree dp (看题解)

时间:2022-07-03 16:41:43

Adam and Tree

感觉非常巧妙的一题。。

如果对于一个已经建立完成的树, 那么我们可以用dp[ i ]表示染完 i 这棵子树, 并给从fa[ i ] -> i的条边也染色的最少颜色数。

mnson[ i ][ 0 ] 和 mnson[ i ][ 1 ]分别表示 i 的儿子的dp值的最大和第二大的值, 那么dp[ i ] = max(mnson[ i ][ 0 ], mnson[ i ][ 1 ] + 1)

根据树链剖分的原理我们知道dp的最大值不超过log(n), 那么每次加入一个新的点, 我们暴力地往上更新dp值, 直到当前的dp值不变。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long using namespace std; const int N = 1e6 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = ;
const double eps = 1e-;
const double PI = acos(-); int n, fa[N], mxson[N][], dp[N]; int main() {
scanf("%d", &n);
for(int i = ; i <= n + ; i++) scanf("%d", &fa[i]);
for(int i = ; i <= n + ; i++) {
int u = i;
while() {
if(u == || dp[u] >= max(mxson[u][], mxson[u][] + )) break;
dp[u] = max(mxson[u][], mxson[u][] + );
if(dp[u] >= mxson[fa[u]][]) {
mxson[fa[u]][] = mxson[fa[u]][];
mxson[fa[u]][] = dp[u];
} else if(dp[u] > mxson[fa[u]][]) {
mxson[fa[u]][] = dp[u];
}
u = fa[u];
}
printf("%d ", mxson[][]);
}
puts("");
return ;
} /*
*/