[Bzoj3162] fishing alone trees and snow _ dp tree tree hash_

Fishing alone trees and snow

Topic links : https://www.lydsy.com/JudgeOnline/problem.php?id=3162


Problem solution :

First, without the same restrictions essence this is a sucker title.

Dp like tree directly.

So if you coupled with the restriction?

We found that no matter how final the same nature, the center of gravity of the tree must be invariant.

Therefore, the focus began to go heavy.

Reference : https: //www.cnblogs.com/zhoushuyu/p/9295759.html

Code :

#include <bits/stdc++.h>

#define N 500010 

using namespace std;

const int mod = 1000000007 ;

char *p1, *p2, buf[100000];

typedef unsigned long long ll;

ll bs1 = 20021214 ;

ll bs2 = 20030315 ;

#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )

int rd() {
    int x = 0;
    char c = nc();
    while (c < 48) {
        c = nc();
    }
    while (c > 47) {
        x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
    }
    return x;
}

int n, inv[N], to[N << 1], nxt[N << 1], head[N], tot, sz[N], w[N], root, rt1, rt2, flag, f[2][N], tmp[N];

ll hs[N];

inline void add(int x, int y) {
    to[ ++ tot] = y;
    nxt[tot] = head[x];
    head[x] = tot;
}

void getroot(int p, int fa) {
    sz[p] = 1;
    w[p] = 0;
    for (int i = head[p]; i; i = nxt[i]) {
        if(to[i] != fa) {
            getroot(to[i], p);
            sz[p] += sz[to[i]];
            w[p] = max(w[p], sz[to[i]]);
        }
    }
    w[p] = max(w[p], n - sz[p]);
    if (w[p] < w[root]) {
        root = p;
    }
}

int C(int n, int m) {
    int re = 1;
    for (int i = n - m + 1; i <= n; i ++ ) {
        re = (ll)re * i % mod;
    }
    for (int i = 1; i <= m; i ++ ) {
        re = (ll)re * inv[i] % mod;
    }
    return re;
}

inline bool cmp(int i, int j) {
    return hs[i] < hs[j];
}

void dfs(int p, int fa) {
    sz[p] = f[0][p] = f[1][p] = 1;
    for (int i = head[p]; i; i = nxt[i]) {
        if (to[i] != fa) {
            dfs(to[i], p);
            sz[p] += sz[to[i]];
        }
    }
    int len = 0;
    for (int i = head[p]; i; i = nxt[i]) {
        if (to[i] != fa) {
            tmp[ ++ len] = to[i];
        }
    }
    sort(tmp + 1, tmp + len + 1, cmp);
    for (int i = 1, j = 1; i <= len; i = j) {
        while (j <= len && hs[tmp[j]] == hs[tmp[i]]) {
            j ++ ;
        }
        f[0][p] = (ll)f[0][p] * C(f[0][tmp[i]] + f[1][tmp[i]] + j - i - 1, j - i) % mod;
        f[1][p] = (ll)f[1][p] * C(f[0][tmp[i]] + j - i - 1, j - i) % mod;
    }
    hs[p] = bs2 * len + sz[p];
    for (int i = 1; i <= len; i ++ ) {
        hs[p] = (hs[p] * bs1) ^ hs[tmp[i]];
    }
}

int main() {
    n = rd();
    inv[0] = inv[1] = 1;
    for (int i = 2; i <= n; i ++ ) {
        inv[i] = (ll)inv[mod % i] * (mod - mod / i) % mod;
    }
    for (int i = 1; i < n; i ++ ) {
        int x = rd(), y = rd();
        add(x, y), add(y, x);
    }
    w[0] = n;
    getroot(1, 0);
    getroot(root, 0);
    for (int i = head[root], last = 0; i; last = i, i = nxt[i]) {
        if (sz[to[i]] * 2 == n) {
            n ++ ;
            if (i == head[root]) {
                head[root] = nxt[i];
            }
            else {
                nxt[last] = nxt[i];
            }
            for (int j = head[to[i]], lst = 0; j; lst = j, j = nxt[j]) {
                if (to[j] == root) {
                    if (j == head[to[i]]) {
                        head[to[i]] = nxt[j];
                    }
                    else {
                        nxt[lst] = nxt[j];
                    }
                    break;
                }
            }
            add(n, root);
            add(root, n);
            add(n, to[i]);
            add(to[i], n);
            rt1 = root;
            rt2 = to[i];
            root = n;
            flag = 1;
            break;
        }
    }
    dfs(root, 0);
    if (!flag) {
        cout << (f[0][root] + f[1][root]) % mod << endl ;
    }
    else if (hs[rt1] == hs[rt2]) {
        cout << (f[0][root] - C(f[1][rt1] + 1, 2) + mod) % mod;
    }
    else {
        cout << ((ll)f[0][rt1] * f[0][rt2] + (ll)f[0][rt1] * f[1][rt2] + (ll)f[1][rt1] * f[0][rt2]) % mod << endl ;
    }
}

Summary : tree hash of the time, if a module to worry about trouble, like me, like two open 233

Guess you like

Origin www.cnblogs.com/ShuraK/p/11421253.html