码迷,mamicode.com
首页 > 其他好文 > 详细

[P4980] 【模板】Polya定理 - Polya定理,欧拉函数

时间:2020-06-16 13:14:59      阅读:66      评论:0      收藏:0      [点我收藏+]

标签:polya定理   ace   max   turn   syn   pre   pow   翻转   alt   

Description

\(n\) 元环的 \(n\) 染色方案数,旋转同构,翻转不同构,颜色可以不用完。

Solution

根据 Polya 定理得出计算式,然后就是非常套路的推导了。

技术图片

对于欧拉函数,暴力计算即可

#include <bits/stdc++.h>

using namespace std;

#define int long long
const int N = 1000005;
const int mod = 1e+9+7;

namespace prime {
    const int MAXN = 1000005;
    bool isNotPrime[MAXN + 1];
    int mu[MAXN + 1], phi[MAXN + 1], primes[MAXN + 1], cnt, a[N];
    inline void euler() {
        isNotPrime[0] = isNotPrime[1] = true;
        mu[1] = 1;
        for (int i = 2; i <= MAXN; i++) {
            if (!isNotPrime[i]) {
                primes[++cnt] = i;
                mu[i] = -1;
            }
            for (int j = 1; j <= cnt; j++) {
                int t = i * primes[j];
                if (t > MAXN) break;
                isNotPrime[t] = true;
                if (i % primes[j] == 0) {
                    mu[t] = 0;
                    break;
                } else {
                    mu[t] = -mu[i];
                }
            }
        }
        for(int i=1;i<=cnt;i++) {
            int p=primes[i];
            for(int j=1;p*j<N;j++) {
                a[p*j]+=mu[j];
            }
        }
        for(int i=1;i<N;i++) {
            a[i]+=a[i-1];
        }
    }
}

int phi(int n) {
    int ans=n,t=n;
    for(int i=2;i*i<=n;i++) {
        if(n%i==0 && !prime::isNotPrime[i]) {
            ans=ans/i*(i-1);
            while(t%i==0) t/=i;
        }
    }
    if(t>1) ans=ans/t*(t-1);
    return ans;
}

int qpow(int p,int q) {return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
int inv(int p) {return qpow(p,mod-2);}

int solve(int n) {
    int ans=0;
    for(int i=1;i*i<=n;i++) {
        if(n%i==0) {
            ans+=qpow(n,i)*phi(n/i)%mod;
            if(i*i!=n) ans+=qpow(n,n/i)*phi(i)%mod;
            ans%=mod;
        }
    }
    ans*=inv(n);
    ans%=mod;
    return ans;
}

signed main() {
    int t,n;
    ios::sync_with_stdio(false);
    prime::euler();
    cin>>t;
    while(t--) {
        cin>>n;
        cout<<solve(n)<<endl;
    }
}

[P4980] 【模板】Polya定理 - Polya定理,欧拉函数

标签:polya定理   ace   max   turn   syn   pre   pow   翻转   alt   

原文地址:https://www.cnblogs.com/mollnn/p/13140279.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!