题目:http://poj.org/problem?id=2154
这种用欧拉函数优化Polya定理真想不到,只能多做题见识见识类型。
证名就不证了,知道方案数L
可以转化为就行了
#include<cstdio>
#include<iostream>
#include<cstring>
#define ll int
using namespace std;
const int N=9999999;
int n,mod;
int pr[N];
bool prime[N];
int k=0;
void isprime(){
int i,j;
memset(prime,true,sizeof(prime));
for(i=2;i<N;i++){
if(prime[i]){
pr[k++]=i;
for(j=i+i;j<N;j+=i)
prime[j]=false;
}
}
}
int phi(int n){
int rea=n,i;
for(i=0;pr[i]*pr[i]<=n;i++){
if(n%pr[i]==0){
rea=rea-rea/pr[i];
while(n%pr[i]==0) n/=pr[i];
}
}
if(n>1)
rea=rea-rea/n;
return rea%mod;
}
ll quick(ll a,ll b,ll k){ //快速幂取模
if(b==0)
return 1;
a%=k; //取下模,否则wa
if(b==1)
return a%k;
ll z=((a%k)*(a%k))%k;
if(b&1){
z=(a*quick(z,b/2,k))%k;
return z;
}
else
return quick(z,b/2,k);
}
int main(){
int t;
isprime();
scanf("%d",&t);
while(t--){
int ans=0;
scanf("%d%d",&n,&mod);
for(int i=1;i*i<=n;i++){
if(i*i==n)
ans=(ans+quick(n,i-1,mod)*phi(i))%mod;
else if(n%i==0){
ans=(ans+quick(n,i-1,mod)*phi(n/i)+quick(n,n/i-1,mod)*phi(i))%mod;
}
}
printf("%d\n",ans%mod);
}
return 0;
}