POJ2154(Pólya定理与欧拉函数优化)

来源:互联网 发布:惠州惠阳区网络问政 编辑:程序博客网 时间:2024/04/30 08:05
 

POJ2154(Pólya定理与欧拉函数优化)

分类: 数论 92人阅读 评论(0) 收藏 举报

题目:Color

 

题意:将正n边形的n个顶点用n种颜色染色,问有多少种方案(答案mod p,且可由旋转互相得到的算一种)

 

先说说Pólya定理

设Q是n个对象的一个置换群,用m种颜色涂染这n个对象,一个对象涂任意一种颜色,则在Q作用下不等价的方案数为:   

|Q|为置换群中置换的个数,为将置换q表示成不相杂的轮换的个数,其中包括单轮换,m为颜色数。

 

分析可以知道本题方案的表达式为:

然后就直接代码了:

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #define N 36000  
  4.   
  5. int p;  
  6.   
  7. int pr[N];  
  8. bool prime[N];  
  9. int k=0;  
  10.   
  11. void isprime()  
  12. {  
  13.     int i,j;  
  14.     memset(prime,true,sizeof(prime));  
  15.     for(i=2;i<N;i++)  
  16.     {  
  17.         if(prime[i])  
  18.         {  
  19.             pr[k++]=i;  
  20.             for(j=i+i;j<N;j+=i)  
  21.             {  
  22.                 prime[j]=false;  
  23.             }  
  24.         }  
  25.     }  
  26. }  
  27.   
  28. int phi(int n)  
  29. {  
  30.     int rea=n,i;  
  31.     for(i=0;pr[i]*pr[i]<=n;i++)  
  32.     {  
  33.         if(n%pr[i]==0)  
  34.         {  
  35.             rea=rea-rea/pr[i];  
  36.             while(n%pr[i]==0)  n/=pr[i];  
  37.         }  
  38.     }  
  39.     if(n>1)  
  40.       rea=rea-rea/n;  
  41.     return rea%p;  
  42. }  
  43.   
  44. int quick_mod(int a,int b)  
  45. {  
  46.     int ans=1;  
  47.     a%=p;  
  48.     while(b)  
  49.     {  
  50.         if(b&1)  
  51.         {  
  52.             ans=ans*a%p;  
  53.             b--;  
  54.         }  
  55.         b>>=1;  
  56.         a=a*a%p;  
  57.     }  
  58.     return ans;  
  59. }  
  60.   
  61. int main()  
  62. {  
  63.     int i,t,n,ans;  
  64.     isprime();  
  65.     scanf("%d",&t);  
  66.     while(t--)  
  67.     {  
  68.         ans=0;  
  69.         scanf("%d%d",&n,&p);  
  70.         for(i=1;i*i<=n;i++)  
  71.         {  
  72.             if(i*i==n)  
  73.                 ans=(ans+quick_mod(n,i-1)*phi(i))%p;  
  74.             else if(n%i==0)  
  75.                 ans=(ans+quick_mod(n,i-1)*phi(n/i)+quick_mod(n,n/i-1)*phi(i))%p;  
  76.         }  
  77.         printf("%d\n",ans%p);  
  78.     }  
  79.     return 0;  
原创粉丝点击