1. 程式人生 > >poj 2409 Let it Bead 一串由n個珠子組成的項鍊用c種顏色染,旋轉/翻轉算一種方案,問一共有多少種不同的染色方案

poj 2409 Let it Bead 一串由n個珠子組成的項鍊用c種顏色染,旋轉/翻轉算一種方案,問一共有多少種不同的染色方案

 

#include <cstdio>
const int mod=1000000007;
int fun(int a,int n)
{
    if(n==1) return a%mod;
    if(n==0) return 1;
    long long t=fun(a,n/2);
    t=(t*t)%mod;//important
    if(n&1) return (t*a)%mod;
    else return t%mod;
}
int euler(int n)
{
    int ans = n;
    for (int i = 2; i <= n; i++) if (n % i == 0)
        {
            ans -= ans / i;
            while (n % i == 0) n /= i;
        }
    if (n > 1) ans -= ans / n;
    return ans;
}
//求(a/b)%p,A必能被B整除,gcd(B,p)=1
__int64 exgcd(__int64 a,__int64 b,__int64& x,__int64& y)
{
    if(b==0) return x=1,y=0,a;
    __int64 r=exgcd(b,a%b,x,y);
    __int64 t=x;
    x=y;
    y=t-(a/b)*y;
    return r;
}
__int64 calc(__int64 a,__int64 b,__int64 mod)
{
    __int64 x,y;
    __int64 r=exgcd(b,mod,x,y);
    x*=a;
    x=(x%mod+mod)%mod;
    return x;
}
int main()
{
    int n, c;
    while(scanf("%d%d", &c, &n)==2&&c)
    {
        if (n == 0)
        {
            printf("0\n");
            continue;
        }
        __int64 ans = 0;
        for (int i = 1; i <= n; i++)
        if (n % i == 0)
            {
                ans += (long long)fun(c, i) * euler(n / i);
            }//列舉個數
        if (n & 1)
        {
            ans += (long long)n * fun(c, n / 2 + 1);
        }
        else
        {
            ans += (long long)n / 2 * (fun(c, n / 2) + fun(c, n / 2 + 1));
        }
        ans /= (2 * n);
       // ans=calc(ans,(long long)2*n,(long long)mod);
        printf("%I64d\n",ans);
    }
    return 0;
}