码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 5868 2016 ACM/ICPC Asia Regional Dalian Online 1001 (burnside引理 polya定理)

时间:2016-09-18 23:39:41      阅读:292      评论:0      收藏:0      [点我收藏+]

标签:

Different Circle Permutation

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 208    Accepted Submission(s): 101


Problem Description
You may not know this but it‘s a fact that Xinghai Square is Asia‘s largest city square. It is located in Dalian and, of course, a landmark of the city. It‘s an ideal place for outing any time of the year. And now:
  
  There are N children from a nearby primary school flying kites with a teacher. When they have a rest at noon, part of them (maybe none) sit around the circle flower beds. The angle between any two of them relative to the center of the circle is always a multiple of 2πN but always not 2πN.
  
  Now, the teacher raises a question: How many different ways there are to arrange students sitting around the flower beds according to the rule stated above. To simplify the problem, every student is seen as the same. And to make the answer looks not so great, the teacher adds another specification: two ways are considered the same if they coincide after rotating.
 

 

Input
There are T tests (T50). Each test contains one integer N1N1000000000 (109). Process till the end of input.
 

 

Output
For each test, output the answer mod 1000000007 (109+7) in one line.
 

 

Sample Input
4 7 10
 

 

Sample Output
3 5 15
 

 

Source
传送门

该题题意:对成环的n个点染黑白两色,其中黑色不能相邻,请问在考虑旋转同构的情况下有几种不一样的方案。
首先不考虑旋转。
  对于一个不考虑旋转的f(n),f(n)=f(n-1)+f(n-2)。
  对于n=1要特殊判断 因为n=1有两种情况,只涂黑和白,只涂黑不符合上述情况可读入1后直接输出2。
  因此f(1)=1,f(2)=3。
  我们可以用矩阵快速幂快速算出f(n)。
  显然的。对于n个点的环
    ①可由n-1个点的环在某个固定位置插入0来生成。该位置两边的情况为00,01,10。插入后为000,001,100。(另n-1由n-2的同样操作生成则有                   0000,0001,1000,为了与情况②对应故列出)
       ②可由n-2个点的环在某个固定位置插入01或10来生成。该位置两边的情况为00,01,10。插入后为0100,0010,0101,1010。
  至此所有情况已经考虑到了。(0000,0001,1000,0100,0010,0101,1010)
接下来考虑同构。
  对于没有约束条件的n个点的环,显然由burnside引理可得方案数$g(n)=frac{1}{n}sum_{i=1}^{n} 2^{gcd(i,j)}$
  因此可得(有点难理解,你把他理解成每个循环相邻在一起的几个点要符合黑点不相邻)$g(n)=frac{1}{n}sum_{i=1}^{n}f(gcd(i,j))$  
                                         g(n)=技术分享

 

    即$g(n)=frac{1}{n}sum_{d|n}^{} \varphi(frac{n}{d})f(d)$
      g(n) 技术分享

 

     以下为代码:
  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 #define clr(x) memset(x,0,sizeof(x))
  7 #define mod 1000000007
  8 #define LL long long
  9 using namespace std;
 10 int inf[40010];
 11 int prime[10000];
 12 int mart1[2][2];
 13 int mart2[2][2];
 14 int mart3[2][2];
 15 void is_prime();
 16 int eular(int x);
 17 void exgcd(int a,int b,int &x,int &y);
 18 void quickmul(int x);
 19 int fu(int x);
 20 int main()
 21 {
 22     int n;
 23     int xi,yi;
 24     int ans;
 25     is_prime();
 26     while(scanf("%d",&n)!=EOF)
 27     {
 28         ans=0;
 29         if(n==1)
 30         {
 31             printf("2\n");
 32             continue;
 33         }
 34         for(int i=1;i*i<=n;i++)
 35         {
 36             if(i*i==n)
 37                 ans=(int)(((LL)ans+(LL)eular(n/i)*(LL)fu(i))%mod);
 38             else if(n%i==0)
 39                 ans=(int)(((LL)ans+((LL)eular(n/i)*(LL)fu(i))%mod+((LL)eular(i)*(LL)fu(n/i))%mod)%mod);
 40         }
 41         exgcd(n,mod,xi,yi);
 42         xi=(xi%mod+mod)%mod;
 43         ans=(int)((((LL)ans*(LL)xi)%mod+mod)%mod);
 44         printf("%d\n",ans);
 45     }
 46 }
 47 void exgcd(int a,int b,int &x,int &y)
 48 {
 49     if(b==0)
 50     {
 51         x=1;
 52         y=0;
 53         return ;
 54     }
 55     exgcd(b,a%b,y,x);
 56     y-=x*(a/b);
 57     return ;
 58 }
 59 void is_prime()
 60 {
 61     clr(inf);
 62     clr(prime);
 63     inf[1]=inf[0]==1;
 64     int tot=0;
 65     for(int i=2;i<40000;i++)
 66     {
 67         if(!inf[i]) prime[tot++]=i;
 68         for(int j=0;j<tot;j++)
 69         {
 70             if(i*prime[j]>40000) break;
 71             inf[i*prime[j]]=1;
 72             if(i%prime[j]==0) break;
 73         }
 74     }
 75     return ;
 76 }
 77 int eular(int x)
 78 {
 79     int ans=x;
 80     for(int j=0;prime[j]*prime[j]<=x;j++)
 81     if(x%prime[j]==0)
 82     {
 83         ans-=ans/prime[j];
 84         while(x%prime[j]==0)
 85             x/=prime[j];
 86     }
 87     if(x>1) ans-=ans/x;
 88     return ans;
 89 }
 90 int fu(int x)
 91 {
 92     if(x==1) return 1;
 93     if(x==2) return 3;
 94     clr(mart1);
 95     clr(mart2);
 96     clr(mart3);
 97     mart1[1][1]=mart1[1][0]=mart1[0][1]=mart2[1][1]=mart2[0][0]=1;
 98     quickmul(x-2);
 99     return (int)(((LL)mart2[1][0]*1+(LL)mart2[1][1]*3)%mod);
100 }
101 void quickmul(int x)
102 {
103     int d;
104     while(x)
105     {
106         if(x&1)
107         {
108             for(int i=0;i<2;i++)
109                 for(int j=0;j<2;j++)
110                 {
111                     d=0;
112                     for(int k=0;k<2;k++)
113                         d=(int)(((LL)d+((LL)mart2[i][k]*(LL)mart1[k][j])%mod)%mod);
114                     mart3[i][j]=d;
115                 }
116             for(int i=0;i<2;i++)
117                 for(int j=0;j<2;j++)
118                     mart2[i][j]=mart3[i][j];
119         }
120         x>>=1;
121         for(int i=0;i<2;i++)
122             for(int j=0;j<2;j++)
123             {
124                 d=0;
125                 for(int k=0;k<2;k++)
126                     d=(int)(((LL)d+((LL)mart1[i][k]*(LL)mart1[k][j])%mod)%mod);
127                 mart3[i][j]=d;
128             }
129             for(int i=0;i<2;i++)
130                 for(int j=0;j<2;j++)
131                     mart1[i][j]=mart3[i][j];
132     }
133     return ;
134 }

 

 
 
 

hdu 5868 2016 ACM/ICPC Asia Regional Dalian Online 1001 (burnside引理 polya定理)

标签:

原文地址:http://www.cnblogs.com/wujiechao/p/5883344.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!