lougu_P2303 [SDOi2012]Longge的问题

传送门:https://www.luogu.org/problem/P2303

这道题要放在一个月前,一眼出答案。可惜,我全忘了.......所以只好翻出了学习Polya定理时的代码......温故一下

求 ∑gcd(i,n)  

就直接看gcd(i,n)的数值有哪些。枚举1~n,它对应的个数就为φ(n/i)。

你可以优化到O(n1/2),这道题就完了。

#include<cstdio>
#define R register
using namespace std; 
typedef long long ll;
ll n,ans;
ll phi(ll x){
    ll y=x,z=x;
    for(ll i=2;i*i<=x;i++){
        if(x%i==0) y=(y/i)*(i-1);
        while(x%i==0) x/=i;
    }
    if(x>1) return y/x*(x-1);
    return y;
}
int main (){
    scanf("%lld",&n);
    ll i=1;
    for(;i*i<n;i++){
        if(n%i==0) ans+=i*phi(n/i)+(n/i)*phi(i);
    }
    if(i*i==n) ans+=i*phi(n/i);
    printf("%lld\n",ans);
    return 0;
}
View Code

Burnside定理: ans=1/n * ∑kf(k)  f(k)为,在置换k下的不动点的个数。

Polya定理:f(k)=ap(k)  a为颜色数,p(k)为循环节的个数。

猜你喜欢

转载自www.cnblogs.com/coclhy/p/11720210.html