zoukankan      html  css  js  c++  java
  • 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_{vin son_n,K-1}) 转移,加上 (siz_{n}-1) 就好。
    所以我们可以列出DP方程

    [egin{matrix} f_{n,0} = sum_{vin son_n}f_{v,K-1} + siz_v \ f_{n,i} = sum_{vin son_n}f_{v,i-1} * [i e 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
    ", 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
    */
    
    Yukkuri si te yi te ne
  • 相关阅读:
    python中常用的模块二
    python中常用的模块一
    python类与类的关系
    python类的成员
    关于python的面向对象
    python内置函数2
    python内置函数
    python fileinput模块
    python生成器
    python 迭代器
  • 原文地址:https://www.cnblogs.com/Gensokyo-Alice/p/13677626.html
Copyright © 2011-2022 走看看