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.