POJ 2154 color (菜啊)

Posted mrh-acmer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2154 color (菜啊)相关的知识,希望对你有一定的参考价值。

Beads of N colors are connected together into a circular necklace of N beads (N<=1000000000). Your job is to calculate how many different kinds of the necklace can be produced. You should know that the necklace might not use up all the N colors, and the repetitions that are produced by rotation around the center of the circular necklace are all neglected.

You only need to output the answer module a given number P.
Input
The first line of the input is an integer X (X <= 3500) representing the number of test cases. The following X lines each contains two numbers N and P (1 <= N <= 1000000000, 1 <= P <= 30000), representing a test case.
Output
For each test case, output one line containing the answer.
Sample Input
5
1 30000
2 30000
3 30000
4 30000
5 30000
Sample Output
1
3
11
70
629

思路 : polya定理+欧拉函数优化
#include<set>
#include<map>
#include<ctime>
#include<queue>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define mod 20101009
#define inf 1000000000
using namespace std;
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
    return x*f;
}
int tot,T;
int n,K,ans;
int pri[1000005];
bool mark[1000005];
int qpow(int a,int b)
{
    int ans=1;a%=K;
    for(int i=b;i;i>>=1,a=a*a%K)
        if(i&1)ans=ans*a%K;
    return ans;
}
int phi(int n)         // 欧拉函数
{
    int ans=n;
    for(int i=1;pri[i]<=sqrt(n);i++)
        if(n%pri[i]==0)
        {
            ans=(ans-ans/pri[i]);
            while(n%pri[i]==0)n/=pri[i];
        }
    if(n!=1)ans=(ans-ans/n);    // 这里是对n进行判断,不是ans;
    return ans%K;
} 
void pre()           // 素数筛法
{
    for(int i=2;i<=1000000;i++)
    {
        if(!mark[i])pri[++tot]=i;
        for(int j=1;j<=tot&&pri[j]*i<=1000000;j++)
        {
            mark[pri[j]*i]=1;
            if(i%pri[j]==0)break;          // 这里要break;
        }
    }
}
int main()
{
    pre();
    T=read();
    while(T--)
    {
        n=read();K=read();
        ans=0;
        for(int i=1;i*i<=n;i++)
            if(n%i==0)
            {
                ans+=phi(i)*qpow(n,n/i-1);
                if(i*i!=n)ans+=phi(n/i)*qpow(n,i-1);        // 因为外面要除n, 直接放在里面
                ans%=K;
            }
        printf("%d
",ans);
    }
    return 0;
}

 

 








以上是关于POJ 2154 color (菜啊)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2154 Color ——Burnside引理

poj2154 Color

POJ 2154 Color

POJ2154 Color

POJ2154 Color(Polya定理)

poj 2154 Color——带优化的置换