poj 2409 Let it Bead【polya定理+burnside引理】

两种置换
旋转:有n种,分别是旋转1个2个……n个,旋转i的循环节数位gcd(i,n)
翻转:分奇偶,对于奇数个,只有一个珠子对一条边的中点,循环节数为n/2+1;对于偶数个,有珠子对珠子和边对边,循环节个数为n/2+1个和n/2个
然后用polya定理即可

#include<iostream>
#include<cstdio>
using namespace std;
long long n,k,ans;
long long ksm(long long a,long long b)
{
    long long r=1;
    while(b)
    {
        if(b&1)
            r=r*a;
        a=a*a;
        b>>=1;
    }
    return r;
}
long long gcd(long long a,long long b)
{
    return !b?a:gcd(b,a%b);
}
int main()
{
    while(scanf("%d%d",&k,&n)&&k+n)
    {
        ans=(n&1)?ksm(k,n/2+1)*n:ksm(k,n/2+1)*n/2+ksm(k,n/2)*n/2;
        for(int i=1;i<=n;i++)
            ans+=ksm(k,gcd(i,n));
        printf("%lld\n",ans/2/n);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lokiii/p/9261823.html