Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 11758 | Accepted: 3783 |
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.
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的圆环,旋转能够到达的属于重复状态,问一共有多少种不同的方案。
由polya定理可知 ans=SUM{ ngcd(k,n) | 0<=k<n} / n ,n<1e9 如果直接算的话肯定会T。由于所有的gcd(k,n)都是n的因子,可以考虑对
相同的因子分成一组,这样找到每一组的个数就好办了, ans=1/n * SUM{ s(d)*nd | d|n ,s(d)为使得gcd(k,n)=d成立的k的个数 },
gcd(k,n)==d --> gcd(k/d,n/d)==1 --> phi(n/d) 。 所以得出s(d)=phi(n/d) ,枚举一下n的因子统计答案就好了。
在计算phi的时候先把sqrt(1e9)之内的素数筛出来再计算会更快,否则会超时。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<map> 5 #include<set> 6 #include<vector> 7 #include<algorithm> 8 #include<cmath> 9 using namespace std; 10 #define LL long long 11 #define PI acos(-1.0) 12 #define N 33333 13 int mod; 14 bool isp[N+10]; 15 vector<int>prime; 16 void init(){ 17 int m=sqrt(N+0.5); 18 for(int i=2;i<=N;i++){ 19 if(!isp[i]){ 20 prime.push_back(i); 21 for(int j=i*i;j<=N;j+=i)isp[j]=1; 22 } 23 } 24 } 25 int qpow(int a,int b,int m){ 26 a%=m; 27 int r=1; 28 while(b){ 29 if(b&1) r=r*a%m; 30 b>>=1; 31 a=a*a%m; 32 } 33 return r%m; 34 } 35 int euler(int n){ 36 int m=sqrt(n+0.5); 37 int ans=n; 38 for(int i=0;prime[i]<=m;++i){ 39 if(n%prime[i]==0){ 40 ans=ans/prime[i]*(prime[i]-1); 41 while(n%prime[i]==0) n/=prime[i]; 42 } 43 } 44 if(n>1) ans=ans/n*(n-1); 45 return ans%mod; 46 } 47 int main() 48 { 49 int t,n,i,j,k,d; 50 init(); 51 scanf("%d",&t); 52 while(t--){ 53 scanf("%d%d",&n,&mod); 54 int ans=0; 55 for(i=1;i*i<n;++i){ 56 if(n%i==0){ 57 (ans+=(euler(n/i)*qpow(n,i-1,mod)%mod))%=mod; 58 59 (ans+=(euler(i)*qpow(n,n/i-1,mod)%mod))%=mod; 60 } 61 } 62 if(i*i==n) (ans+=(euler(i)*qpow(n,i-1,mod)%mod))%=mod; 63 cout<<ans<<endl; 64 } 65 return 0; 66 }