2154 Color//POLYA

Color
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 2967   Accepted: 1016

Description

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

Source

POJ Monthly,Lou Tiancheng
/* 题目求N色N个不等价置换个数(mod p) N<= 10^9 置换只有旋转一种方式,那么共有n个置换 基本知识:环的个数为gcd(n , i) , 长度L=n / gcd(n , i) 其中 i 为转的位子数 普通求法: ∑n^( gcd(n,i) ) 0<=i<n 复杂度过高 优化:枚举环的长度L 枚举优化: L可以从1取到sqrt(n) ,因为L|n , n/L | n 对于每个L,我们再看有几个i满足条件 n/L = gcd(n , i) 那么令 a=n/L = gcd(n , i) , 再设i = at 那么当且仅当gcd(L,t)=1时候,才有gcd(n,i) = a 显然满足条件的i的个数就是t的个数也就是phi(L) 那么最后统计一下就是 ∑(phi(L) * N^(L-1) ) % p (L即枚举值) */ #include<cstdio> #include<cstring> const int N=40000; int prime_num; int prime[20000]; int n,p; bool isprime[N]; void init() { memset(isprime,true,sizeof(isprime)); for(int i=2;i*i<N;i++) if(isprime[i]) { for(int j=i*i;j<N;j+=i) isprime[j]=false; } prime_num=0; for(int i=2;i<N;i++) if(isprime[i]) prime[++prime_num]=i; } int phi(int x)//欧拉函数 { int num=x; for(int i=1;prime[i]*prime[i]<=x;i++) { if(x%prime[i]==0) { num = (num/prime[i])*(prime[i]-1); while(x % prime[i] == 0) { x = x / prime[i]; } } } if(x != 1) num = (num/x)*(x-1); return num % p; } int exp(int x, int y) { long long i; if(y == 0) return 1; if(y == 1) return x%p; i = exp(x,y/2); i = (i*i)%p; if(y&1) i=i*x; return i % p; } int main() { int cas; scanf("%d",&cas); init(); while(cas--) { int ans=0; scanf("%d%d",&n,&p); for(int i=1;i*i<=n;i++) { if(i*i==n) { ans+=phi(i)*exp(n,i-1); ans%=p; break; } else if(n%i==0)//i,n/i都是质因子 { ans+=phi(i)*exp(n,n/i-1); ans+=phi(n/i)*exp(n,i-1); ans%=p; } } printf("%d/n",ans); } return 0; }

你可能感兴趣的:(Integer,input,each,output,colors,Numbers)