polya定理+欧拉函数优化,1641ms水过,具体参考的解题报告:http://www.cnblogs.com/staginner/archive/2012/03/08/2385052.html
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 typedef long long LL; 5 int n,p; 6 int get_Eu(int x) 7 { 8 int i; 9 int ans=x; 10 for(i=2;i*i<=x;i++) 11 { 12 if(x%i==0) 13 { 14 while(x%i==0) x/=i; 15 ans=ans/i*(i-1); 16 } 17 } 18 if(x>1) ans=ans/x*(x-1); 19 return ans; 20 } 21 int pow(LL x,LL n) 22 { 23 if(n==0) return 1; 24 if(n==1) return x%p; 25 LL tem=pow(x,n/2); 26 tem=(tem*tem)%p; 27 if(n%2) tem=(tem*(x%p))%p; 28 return (int)tem; 29 } 30 int main() 31 { 32 int cas; 33 cin>>cas; 34 while(cas--) 35 { 36 cin>>n>>p; 37 int i,j,k,tem,sum=0; 38 for(i=1;i*i<n;i++) 39 { 40 if(n%i==0) 41 { 42 tem=get_Eu(n/i); 43 if(tem) sum=(sum+((tem%p)*pow((LL)n,(LL)(i-1)))%p)%p; 44 tem=get_Eu(i); 45 if(tem) sum=(sum+((tem%p)*pow((LL)n,(LL)(n/i-1)))%p)%p; 46 } 47 } 48 if(i*i==n) 49 { 50 tem=get_Eu(n/i); 51 if(tem) sum=(sum+((tem%p)*pow((LL)n,(LL)(i-1)))%p)%p; 52 } 53 printf("%d\n",sum); 54 } 55 return 0; 56 }