题意:
n个珠子的环,之多着n种颜色,考虑旋转,不考虑翻转。问模P的方案数。
思路:
1<= N <= 1000000000 我们运用polya定理,ans=(1/N)*sigma(n,gcd(i,n));
T<= 3500组数据直接做怕是会TLE
这里我们知道[0,n-1]中有许多gcd为1的数据不必一一遍历这些数据有euler(n)个
我们还能得出gcd为2的有euler(n/2)个
只要一一遍历n的约数即可O(sqrt(n))的时间复杂度
#include<stdio.h>
#include<iostream>
#define long long int
using namespace std;
int n,p;
int euler(int n){ //¡¤¦Ì??euler(n)
int res=n,a=n;
for(int i=2;i*i<=a;i++){
if(a%i==0){
res=res/i*(i-1);//?¨¨??DD3y¡¤¡§¨º??a¨¢?¡¤¨¤?1?D??¨ºy?Y¦Ì?¨°?3?
while(a%i==0) a/=i;
}
}
if(a>1) res=res/a*(a-1);
return res%p;
}
int qpow(int a,int b)
{
int ans=1;
while(b)
{
if(b&1) ans=(ans*a)%p;
a=(a*a)%p;
b>>=1;
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&p);
int ans=0;
for(int i=1;i*i<=n;i++)
{
if(n%i==0)
{
ans=(ans+(euler(n/i)*qpow(n%p,i-1)))%p;
if(i*i!=n)
ans=(ans+(euler(i)*qpow(n%p,(n/i)-1)))%p;
}
}
printf("%d\n",ans);
}
return 0;
}