L3-032 The question about depth-first search and reverse order pair should not be difficult, right?

Portal
idea:
Reference from "I am a small snail"
namo, except for remake, can it be as strong as the two teachers
? Consider a separate dfs sequence, whether the point pair with a parent-child relationship is reversed, and there is no parent-child relationship. The probability of whether the point pairs are reversed or not each accounts for 1 2 \frac{1}{2}21
Count the dfs ordinal number, consider maintaining the dfs ordinal number of a subtree, the dfs ordinal number of the current node is equal to ( ∏ \prod dfs ordinal of the subtree rooted at its child node)× \times× (number of permutations of child nodes)
code:
f[] is the number of dfs ordering schemes with u as the subtree, cntRev is the number of reverse order pairs determined in a dfs order, cntNum is the number of reverse order pairs determined in a dfs order Number, num is the number of point pairs without parent-child relationship

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const ll mod = 1e9 + 7;
const ll N = 3e5 + 10;

vector<ll> g[N];
ll tree[N];
ll n, rt;

ll qpow(ll x, ll n) {
    
    
    ll res = 1;
    while (n) {
    
    
        if (n & 1) res = res * x % mod;
        x = x * x % mod;
        n >>= 1;
    }
    return res;
}

ll lowbit(ll x) {
    
    
    return x & (-x);
}

void add(ll p, ll x) {
    
    
    while (p <= n) {
    
    
        tree[p] = (tree[p] + x) % mod;
        p += lowbit(p);
    }
}

ll query(ll p) {
    
    
    ll res = 0;
    while (p) {
    
    
        res = (res + tree[p]) % mod;
        p -= lowbit(p);
    }
    return res;
}

ll cntRev = 0, cntNum = 0;
ll f[N];
ll fac[N];

void dfs(ll x, ll p) {
    
    
    f[x] = 1;
    for (auto to : g[x]) {
    
    
        if (to == p) continue;
        cntRev = (cntRev + query(n) - query(to) + mod) % mod;
        cntNum = (cntNum + query(to)) % mod;
        add(to, 1);
        dfs(to, x);
        f[x] = f[x] * f[to] % mod;
        add(to, -1);
    }
    ll num = (x == rt ? g[x].size() : g[x].size() - 1);
    f[x] = f[x] * fac[num] % mod;
}


signed main() {
    
    
    ios::sync_with_stdio(false), cin.tie(nullptr);

    fac[0] = 1;
    for (ll i = 1; i < N; ++i) fac[i] = fac[i - 1] * i % mod;

    cin >> n >> rt;
    for (ll i = 1; i <= n - 1; ++i) {
    
    
        ll x, y;
        cin >> x >> y;
        g[x].push_back(y);
        g[y].push_back(x);
    }

    add(rt, 1);
    dfs(rt, -1);

    ll num = ((n * (n - 1) % mod * qpow(2, mod - 2) % mod - cntRev - cntNum) % mod + mod) % mod;
    ll ans = f[rt] * (cntRev + num * qpow(2, mod - 2) % mod) % mod;
    cout << ans << endl;
}

Guess you like

Origin blog.csdn.net/qq_39602052/article/details/124461408