BZOJ 1478 & 1488 & 1815 & Sgu282 Isomorphism

Edge coloring, vertex substitution results in a homogeneous, violence has replaced the enumeration $ n! $ Species, considering how many have the same displacement contribution.

Substitution of a point, with a vertex $ U $ $ f: u \ to p [ u] $, edge $ (u, v) $ substitution $ f ':( u, v) \ to (p [u] , p [v]) $.
When $ u, v $ simultaneously in one cycle, cycle length of $ $ L, then this edge $ (u, v) $ is the number of cycles of $ \ lfloor \ frac {L} {2} \ rfloor $.
When $ u, v $, respectively, a length of $ L_1 $, when $ L_2 are $ cycle while $ (u, v) $ cycle length formed is $ \ text {lcm} (L_1 , L_2) $, circulating a number of $ \ gcd (L_1, L_2) $.
The number of cycles with only about $ L $, then $ L $ can see how composed.
Now is the n-$ $ vertices divided into several cycles. With $ m $ cycles, each cycle length of $ L_1, L_2, ..., L_m $, where $ 0 <L_1 \ leq L_2 \ leq ... \ leq L_m $, $ L_1 + L_2 + ... + L_m = n $.
After determining a points system, ask about how many replacement.
Corresponding to the n-$ $ $ m $ elements into boxes, each box size L_i $ $, program number $ \ frac {n!} { L_1! L_2! ... L_m!} $, Each box with a $ (L_i - 1)! $ permutations mode, then the program number $ \ frac {n!} { L_1L_2 ... L_m} $, if $ L_i = L_ {i + 1 } = .. . = L_ {i + k - 1} $, $ k $ a box which is no difference, then you have divided by $ k $!.
Therefore, the $ L_1 ... L_m $ determined, there $$ \ {L_1L_2 ... L_mk_1! K_2 ! ... k_t!} Frac {n!} $$
wherein L $ t $ $ $ indicates there $ t $ kinds of values, each value there was $ k_i $ times.

For this channel BZOJ1488 FIG isomorphic graph corresponds to the edges is infected with two colors, white color indicates the presence of the edge, there is no side that represents black is $ $ m = 2 in the case.

#include <bits/stdc++.h>
#define ll long long

const  int N = 100 ;
int n, m, MOD;
int fac [N] years, tol;
int num [N] cnt [N];

int gcd(int a, int b) {
    while (b) {
        a %= b;
        std::swap(a, b);
    }
    return a;
}

int qp(int a, int b = MOD - 2) {
    int ans = 1;
    while (b) {
        if (b & 1) ans = 1LL * a * ans % MOD;
        a = 1LL * a * a % MOD;
        b >>= 1;
    }
    return ans;
}

void Ma(int &a) {
    if (a >= MOD) a -= MOD;
    if (a < 0) a += MOD;
}

template<class T>
void Mb(T &a) {
    static const int mod = MOD - 1;
    a %= mod;
    if (a >= mod) a -= mod;
    if (a < 0) a += mod;
}

void dfs(int cur, int left) {
    if (!left) {
        int a = 1;
        ll b = 0;
        for (int i = 1; i <= tol; i++) {
            a = 1LL * a * qp(num[i], cnt[i]) % MOD * fac[cnt[i]] % MOD;
            b += cnt[i] * (cnt[i] - 1) / 2 * num[i] + num[i] / 2 * cnt[i];
            for (int j = i + 1; j <= tol; j++)
                b += cnt[i] * cnt[j] * gcd(num[i], num[j]);
        }
        a = 1LL * fac[n] * qp(a) % MOD;
        Mb (b);
        Ma(Ans += 1LL * a * qp(m, (int)b) % MOD);
    }
    if (cur > left) return;
    dfs(cur + 1, left);
    for (int i = 1; i * cur <= left; i++) {
        ++tol;
        num[tol] = cur; cnt[tol] = i;
        dfs(cur + 1, left - i * cur);
        --tol;
    }
}

int main () {
    scanf("%d%d%d", &n, &m, &MOD);
    for (int i = fac[0] = 1; i < N; i++)
        do [i] = i * is 1LL * [i - 1 ]% MOD;
    dfs(1, n);
    printf("%lld\n", 1LL * Ans * qp(fac[n]) % MOD);
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/Mrzdtz220/p/12232133.html