PolyA theorem Summary

Source: Internet
Author: User

Reprint please indicate the source, thank you http://blog.csdn.net/ACM_cxlove? Viewmode = contents by --- cxlove

Recently, I have come into contact with the polyA counting theorem. We recommend that you study the replacement group before.

It only covers the meaning of deep theorem and proofs.

Http://poj.org/problem? Id = 2409

Raw polyA, the data range is very small, and I is directly enumerated. For the cycle section that rotates each conversion, the length is gcd (I, n). For flip, if it is an odd number, otherwise, half is n/2 + 1, and half is n/2 + 1. The first code is well written in many places, and the loop is redundant during flip.

#include<iostream>#include<cstdio>#include<cstring>#define LL long longusing namespace std;LL gcd(LL a,LL b){return b==0?a:gcd(b,a%b);}int c,s;LL Pow(int a,int b){return b==0?1:Pow(a,b-1)*a;}LL polya(){LL sum=0;for(int i=1;i<=s;i++)sum+=Pow(c,gcd(s,i));if(s&1)sum+=s*Pow(c,(s>>1)+1);else{for(int i=1;i<=s;i++)if(i&1)sum+=Pow(c,(s>>1)+1);elsesum+=Pow(c,s>>1);}return sum/2/s;}int main(){while(scanf("%d%d",&c,&s)!=EOF&&c+s)printf("%I64d\n",polya());return 0;}

Http://poj.org/problem? Id = 1286

This is also a template question. We also need to consider turning and rotating. However, we tried to add the Euler's function optimization, which has always been enumeration I, and gcd (I, n) is the number of loops, the length of each loop is L = N/gcd (I, n). We can enumerate l directly.

It proves that weak food cannot be clearly explained at once.

Common method: Σ n ^ (gcd (n, I) 0 <= I <n complexity is too high

Optimized: length of the enumeration ring l

Enumeration optimization: l can get SQRT (n) from 1, because l | N, N/L | n

For each L, let's look at several I conditions.

N/L = gcd (n, I)

Then set a = N/L = gcd (n, I), and then set I =

Then, gcd (n, I) = A is available only when gcd (L, t) = 1.

Obviously, the number of I that meet the condition is the number of T, that is, Phi (l)

Then the final statistics is sigma (PHI (l) * n ^ (L-1) % P (L is the enumerated value)

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#define LL long longusing namespace std;LL gcd(LL a,LL b){return b==0?a:gcd(b,a%b);}int c,s;LL eular(int n){LL sum=1;for(int i=2;i<=sqrt(1.0+n);i++)if(n%i==0){sum*=(i-1);n/=i;while(n%i==0){sum*=i;n/=i;}}if(n>1)sum*=(n-1);return sum;}LL Pow(int a,int b){LL ret=1;while(b){if(b&1)ret=ret*a;a=a*a;b>>=1;}return ret;}LL polya(){LL sum=0;for(int i=1;i<=s;i++)if(s%i==0)     sum+=Pow(c,i)*eular(s/i);if(s&1)sum+=s*Pow(c,(s>>1)+1);elsesum+=s/2*(Pow(c,(s>>1)+1)+Pow(c,s>>1));return sum/2/s;}int main(){c=3;while(scanf("%d",&s)!=EOF&&s!=-1){if(s==0) printf("0\n");elseprintf("%I64d\n",polya());}return 0;}

Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 3923

Let's continue with the question of "brute force.

#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#define MOD 1000000007 #define LL long longusing namespace std;int prime[30]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,    47,53,59,61,67,71,73,79,83,89,97,101},cnt=25;LL n,m;LL eular(LL num){    LL ret=1;    for(int i=0;i<cnt&&prime[i]<=num;i++)        if(num%prime[i]==0){            ret*=(prime[i]-1);            num/=prime[i];            while(num%prime[i]==0){                num/=prime[i];                ret*=prime[i];            }        }        if(num>1)            ret*=(num-1);        return ret%MOD;}LL Pow(LL a,LL b){    LL ret=1;    while(b){        if(b&1)            ret=(ret*a)%MOD;        a=(a*a)%MOD;        b>>=1;    }    return ret;}LL Polya(){    LL sum=0,i;    for(i=1;i*i<n;i++){        if(n%i==0){            sum=(sum+eular(i)*Pow(m,n/i))%MOD;            sum=(sum+eular(n/i)*Pow(m,i))%MOD;        }    }    if(i*i==n)        sum=(sum+eular(i)*Pow(m,i))%MOD;    if(n&1)        sum=(sum+n*Pow(m,n/2+1))%MOD;    else        sum=(sum+n/2*(Pow(m,n/2)+Pow(m,n/2+1)))%MOD;    return (sum*Pow(2*n,MOD-2))%MOD;}int main(){    LL t,cas=0;    scanf("%I64d",&t);    while(t--){        scanf("%I64d%I64d",&m,&n);        printf("Case #%I64d: %I64d\n",++cas,Polya());    }    return 0;}

Http://poj.org/problem? Id = 2154

The question is similar, but the data is very big. If the violent enumeration I is definitely not good, you must use the Euler function optimization to search for the factor n.

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#define LL long long#define N 1000000000using namespace std;int n,p;bool flag[40000]={0};int prime[40000],cnt=0;void Prime(){for(int i=2;i<=sqrt(N+1.0);i++){if(flag[i]) continue;prime[cnt++]=i;for(int j=2;j*i<=sqrt(N+1.0);j++)flag[i*j]=true;}}LL gcd(LL a,LL b){return b==0?a:gcd(b,a%b);}int eular(int m){int sum=1;for(int i=0;i<cnt&&prime[i]<=m;i++)if(m%prime[i]==0){sum*=(prime[i]-1);m/=prime[i];while(m%prime[i]==0){sum*=prime[i];m/=prime[i];}}if(m>1)sum*=(m-1);return sum%p;}int Pow(int a,int b){int ret=1;a=a%p;while(b){if(b&1)ret=(ret*a)%p;a=(a*a)%p;b>>=1;}return ret;}int polya(){int sum=0;int i=1;for(;i*i<n;i++)if(n%i==0)sum=(sum+eular(i)*Pow(n,n/i-1)+eular(n/i)*Pow(n,i-1))%p;if(i*i==n)sum=(sum+eular(i)*Pow(n,i-1))%p;return sum;}int main(){int t;Prime();scanf("%d",&t);while(t--){scanf("%d%d",&n,&p);printf("%d\n",polya());}return 0;}

Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 1812

It is also a typical polyA, just launch each situation. However, a large number is required.

The rotation method is only 0, 90, and 180,270 degrees.
If the rotation is 0 degrees, the number of replicas is N * n.
If n is an even number, the number of replicas is N * n/4. If n is an odd number, the number of replicas is (N * N-1)/4 + 1.
If n is an even number, the number of replicas is N * n/2, and N is an odd number, then the number of replicas is (N * N-1)/2 + 1.
If n is an even number, the number of replicas is N * n/4, and N is an odd number, then the number of replicas is (N * N-1)/4 + 1.

There are two types of reflection along diagonal reflection and two types of reflection along the midpoint of the opposite edge.
When N is an even number, the number of replicas reflected along the midpoint of the edges is N * n/2.
Number of replacement rotations (N * n-n)/2 + n
When N is an odd number, the number of replicas (N * n-n)/2 + N are reflected along the midpoint of the edge.
Number of replacement rotations (N * n-n)/2 + n

To sum up, the number of solutions for N * n rectangle dyeing with M colors L
S = m ^ (N * n) + m ^ (n * n + 3)/4) + M (n * n + 1)/2) + m ^ (n * n + 3)/4) (when rotating)

N is an odd number. L = (S + 4 * m ^ (n * n + N)/2)/8

N is an even number L = (S + 2 * m ^ (n * n + N)/2) + 2 * m (N * n/2)/8

Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 3547

Color the eight vertices of the cube. In 24 cases, it's okay to understand the problem.

The final result is ans = 17 * x ^ 2 + 6 * x ^ 4 + x ^ 8.

But it also has to use large numbers, so it won't hurt Java.

Http://poj.org/problem? Id = 2888

This is not the same as the previous one. Given the Restriction Relationship between K groups, A and B cannot be adjacent. Considering the 10 classic matrix problems, we construct a matrix and perform a rapid Power Multiplication. Because it is a loop, for example, the first part is a-> B-> C-> D-> A, and the last part is to return to a. Therefore, the final solution is the diagonal sum of the matrix. Classic question, like one

/* ID: cxloveprob: poj 2888 magic braceletdata: 2012.4.11hint: Restricted polyA, matrix fast power multiplication, modulo inverse element, various classic */
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#define LL long long#define N 1000000000#define MOD 9973using namespace std;int n,m,p,k;bool flag[40000]={0};int prime[40000],cnt=0;struct matrix{int m[15][15];}mat;matrix operator*(matrix m1,matrix m2){matrix ans;for(int i=1;i<=m;i++)for(int j=1;j<=m;j++){ans.m[i][j]=0;for(int k=1;k<=m;k++)ans.m[i][j]=(ans.m[i][j]+m1.m[i][k]*m2.m[k][j])%MOD;}return ans;}matrix operator^(matrix m1,int num){matrix ans;memset(ans.m,0,sizeof(ans.m));for(int i=1;i<=m;i++) ans.m[i][i]=1;while(num){if(num&1) ans=ans*m1;m1=m1*m1;num>>=1;}return ans;}void Prime(){for(int i=2;i<=sqrt(N+1.0);i++){if(flag[i]) continue;prime[cnt++]=i;for(int j=2;j*i<=sqrt(N+1.0);j++)flag[i*j]=true;}}int eular(int m){int sum=1;for(int i=0;i<cnt&&prime[i]<=m;i++)if(m%prime[i]==0){sum*=(prime[i]-1);m/=prime[i];while(m%prime[i]==0){sum*=prime[i];m/=prime[i];}}if(m>1)sum*=(m-1);return sum%MOD;}int Pow(int a,int b){int ret=1;a=a%MOD;while(b){if(b&1)ret=(ret*a)%MOD;a=(a*a)%MOD;b>>=1;}return ret;}void debug(matrix t){for(int i=1;i<=m;i++){for(int j=1;j<m;j++)printf("%d ",t.m[i][j]);printf("%d\n",t.m[i][m]);}}int slove(int num){matrix temp=mat^num;int ret=0;for(int i=1;i<=m;i++)ret=(ret+temp.m[i][i])%MOD;return ret;}int polya(){int sum=0;int i=1;for(;i*i<n;i++)if(n%i==0)sum=(sum+eular(i)*slove(n/i)+eular(n/i)*slove(i))%MOD;if(i*i==n)sum=(sum+eular(i)*slove(i))%MOD;return (sum*Pow(n%MOD,MOD-2))%MOD;}int main(){int t;Prime();scanf("%d",&t);while(t--){scanf("%d%d%d",&n,&m,&k);for(int i=1;i<=m;i++)for(int j=1;j<=m;j++)mat.m[i][j]=1;while(k--){int a,b;scanf("%d%d",&a,&b);mat.m[a][b]=mat.m[b][a]=0;}printf("%d\n",polya());}return 0;}

Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 2865

What is the question of AC God? It looks similar to the previous question, but the number of colors here is too large to use a matrix, but considering that the diagonal line of the matrix is all 0 and the rest is all 1, you can deduce the formula.

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#define LL long long#define N 1000000000#define MOD 1000000007using namespace std;LL n,m,k;bool flag[40000]={0};int prime[40000],cnt=0;void Prime(){    for(int i=2;i<=sqrt(N+1.0);i++){        if(flag[i]) continue;        prime[cnt++]=i;        for(int j=2;j*i<=sqrt(N+1.0);j++)            flag[i*j]=true;    }}int eular(int m){    int sum=1;    for(int i=0;i<cnt&&prime[i]<=m;i++)        if(m%prime[i]==0){            sum*=(prime[i]-1);            m/=prime[i];            while(m%prime[i]==0){                sum*=prime[i];                m/=prime[i];            }        }        if(m>1)            sum*=(m-1);        return sum%MOD;}LL Pow(LL a,LL b){    LL ret=1;    a=a%MOD;    while(b){        if(b&1)            ret=(ret*a)%MOD;        a=(a*a)%MOD;        b>>=1;    }    return ret;}LL slove(LL p,LL k){    LL ans=Pow(p-1,k);    if(k&1)        ans=(ans+MOD-(p-1))%MOD;    else        ans=(ans+p-1)%MOD;    return ans;}int polya(){    int sum=0;    int i=1;    for(;i*i<n;i++)        if(n%i==0)            sum=(sum+eular(i)*slove(m-1,n/i)+eular(n/i)*slove(m-1,i))%MOD;    if(i*i==n)        sum=(sum+eular(i)*slove(m-1,i))%MOD;    return (sum*Pow(n%MOD,MOD-2))%MOD;}int main(){        Prime();    while(scanf("%I64d%I64d",&n,&m)!=EOF)        printf("%d\n",(m*polya())%MOD);    return 0;}

Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 3441

The so-called "body" of AC is to be studied.

Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 2481

If you have questions about Chengdu in, you will remember to teach me.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.