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


    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)= frac{1}{n} sum_{d|n}^{} varphi(frac{n}{d}) f(d)$
         以下为代码:
      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
    ");
     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
    ",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 }
     
     
     
  • 相关阅读:
    Fiddler常用命令
    在Fiddler中添加自己所需的显示列
    清除微信小程序的缓存
    关于接口幂等性的一些总结
    外边距塌陷如何解决?
    CSS背景属性
    CSS链接伪类:超链接的状态
    CSS三大特性
    CSS块元素、行内元素、行内块元素的转换
    CSS行内块元素(内联元素)
  • 原文地址:https://www.cnblogs.com/wujiechao/p/5883344.html
Copyright © 2020-2023  润新知