1. 程式人生 > 實用技巧 >CF771C Bear and Tree Jumps

CF771C Bear and Tree Jumps

CF771C Bear and Tree Jumps

直接考慮換根。
但是有個K,不好搞,那就多存點,記錄 \(f_{n,j}\) 為與 \(n\) 距離為 \(j\) 的點的答案(\(f_{n,0}\) 即為自己的答案),那麼可以知道,對於距離不為 \(K\) 的倍數的點,可以直接距離加一,對於距離為 \(K\) 的倍數的點?對於 \(f_{n,0}\) 可以直接從 \(f_{v\in son_n,K-1}\) 轉移,加上 \(siz_{n}-1\) 就好。
所以我們可以列出DP方程

\[\begin{matrix} f_{n,0} = \sum_{v\in son_n}f_{v,K-1} + siz_v \\ f_{n,i} = \sum_{v\in son_n}f_{v,i-1} * [i\ne 0] \end{matrix}\]

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

typedef long long ll;
const ll MAXN = 1e6+10;

struct edge {
    ll nt, to;
} E[MAXN];

ll N, head[MAXN], cnt = -1, ans = 0, K, f[MAXN][7], siz[MAXN];

void add(ll, ll);
void dfs(ll, ll);
void dfs2(ll, ll);

int main() {
    memset(head, -1, sizeof(head));
    scanf("%lld%lld", &N, &K);
    for (ll i = 1, x, y; i < N; i++) {
        scanf("%lld%lld", &x, &y);
        add(x, y);
        add(y, x);
    }
    dfs(1, 0);
    dfs2(1, 0);
    printf("%lld\n", ans / 2);
    return 0;
}

void dfs2(ll n, ll ff) {
    ll t[7] = {0};
    if (ff) {
        for (ll i = 1; i < K; i++) {
            t[i] = f[ff][i] - f[n][i-1];
        }
        t[0] = f[ff][0] - f[n][K-1] - siz[n];
        for (ll i = 1; i < K; i++) {
            f[n][i] += t[i-1];
        }
        f[n][0] += t[K-1] + (N - siz[n]);
    }
    ans += f[n][0];
    for (ll i = head[n]; ~i; i = E[i].nt) {
        ll v = E[i].to;
        if (v == ff) continue;
        else {
            dfs2(v, n);
        }
    }
}

void dfs(ll n, ll ff) {
    siz[n] = 1;
    for (ll i = head[n]; ~i; i = E[i].nt) {
        ll v = E[i].to;
        if (v == ff) continue;
        else {
            dfs(v, n);
            siz[n] += siz[v];
            f[n][0] += f[v][K-1] + siz[v];
            for (ll i = 1; i < K; i++) {
                f[n][i] += f[v][i-1];
            }
        }
    }
}

void add(ll x, ll y) {
    cnt++;
    E[cnt].to = y;
    E[cnt].nt = head[x];
    head[x] = cnt;
}

/*
6 2
1 2 
1 3 
2 4 
2 5
4 6
ans :20

6 1
1 2 
1 3 
2 4 
2 5
4 6
ans :31

7 2
1 2
2 3
3 4
4 5
5 6
6 7
ans :34
*/