1. 程式人生 > 其它 >快來看,大資料兩地三中心的容災也可以如此省心!

快來看,大資料兩地三中心的容災也可以如此省心!

題源:

Luogu4980.

題意:

\(n\) 點環,每個點可以寫 \(1 \ldots n\) 中的一個數,問有多少旋轉後本質不同的染色方案。

\(\rm Analysis:\)

\(\operatorname{burnside}\) 引理,仍然是考慮每個置換操作的等價類個數,發現對於一個往後 \(k\) 的置換,一共會構成 \(\gcd(n, k)\) 個環,環內部是同色,所以所求就是:

\[\begin{aligned} \sum _ {i = 1} ^ n n ^ {(n, i)} &= \sum _ {d \mid n} n ^ d \sum _ {i = 1} ^ n [(i, n) = d] \\ &= \sum _ {d \mid n} n ^ d \sum _ {i = 1} ^ {\lfloor \frac{n}{d} \rfloor} [(i, \frac{n}{d}) = 1] \\ &= \sum _ {d \mid n} n ^ d \varphi(\frac{n}{d}) \end{aligned} \]

列舉約數即可,暴力按照定義求 \(phi\)

一定要記得 polya 定理最後要取平均值!

\(\rm Code:\)

using i64 = long long;
const int md = 1e9 + 7;

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

    int T;
    std::cin >> T;
    while (T--) {
        int n;
        std::cin >> n;
        i64 res = 0;
        for (int i = 1; i * i <= n; ++i) {
            if (n % i == 0) {
                res = (res + pwer(n, i) * phi(n / i) % md) % md;
                if (i * i != n) 
                    res = (res + pwer(n, n / i) * phi(i) % md) % md;
            }
        }

        std::cout << res * pwer(n, md - 2) % md << '\n';
    }
}
我不想就這樣淪陷,迷失在黑夜,我將燃燒這生命,就算再壯烈。