前两天看了Polya定理,今天做了一道HDU的题,伤心了,超时。。。我的高精度超时。。。看了statistics,大部分是用JAVA过的。要好好学JAVA。。。
Problem Description
话说就是因为这个游戏,Lele已经变成一个名人,每当他一出现在公共场合,就有无数人找他签名,挑战。 为了防止引起社会的骚动,Lele决定还是乖乖呆在家里。 在 家很无聊,Lele可不想像其他人一样每天没事在家数钱玩,于是他就开始数棋盘。他想知道,一个有N×N个格子的正方形棋盘,每个格子可以用C种不同颜色 来染色,一共可以得到多少种不同的棋盘。如果一个棋盘,经过任意旋转,反射后变成另一个棋盘,这两个棋盘就是属于同一种棋盘。 比如当N=C=2的时候,有下面六种不同的棋盘
现在告诉你N和C,请你帮帮Lele算算,到底有多少种不同的棋盘
本题目包含多组测试,请处理到文件结束。 每组测试数据包含两个正整数N和C(0<N,C,<31),分别表示棋盘的大小是N×N,用C种颜色来进行染色。
对于每组测试,在一行里输出答案。
话说这题就是Polya定理,公式:S=(C^M1+C^M2+...+C^Mn)/G G是阶数,Mi是各阶循环节的个数。 根据题意,有旋转和翻转两种情况,G=8,旋转4,翻转4。 对于旋转,以2*2为例很容易知道有旋转90度,180度,270度和360度,循环分别为(1,2,3,4);(1,3)(2,4);(1,4,3,2);(1)(2)(3)(4). 翻转则是枚举对称轴,正方形又分为沿对角线和沿边的中垂线两种。 附超时代码。。。。计算结果是正确的。。。。。:
TLE_CODE #include<iostream> struct M { int m[3000]; }; using namespace std; int n,cou; M Add(M a,M b) { M res; memset(res.m,0,sizeof(res.m)); res.m[0]=a.m[0]>b.m[0]?a.m[0]:b.m[0]; int i; int t=0; for(i=1;i<=res.m[0];i++) { res.m[i]=(a.m[i]+b.m[i]+t); t=res.m[i]/10; res.m[i]%=10; } if(t) { res.m[++res.m[0]]=t%10; t/=10; } return res; } M Mult(M a,M b) { M res; memset(res.m,0,sizeof(res.m)); res.m[0]=a.m[0]+b.m[0]-1; int i,j; for(i=1;i<=b.m[0];i++) { int t=0; for(j=1;j<=a.m[0];j++) { res.m[i+j-1]+=a.m[j]*b.m[i]+t; t=res.m[i+j-1]/10; res.m[i+j-1]%=10; } while(t) { res.m[i+j-1]=t%10; t/=10; if(i+j-1>res.m[0]) res.m[0]=i+j-1; j++; } } return res; } M Div(M a,int b) { int i; int left=0; M res; memset(res.m,0,sizeof(res.m)); res.m[0]=a.m[0]; for(i=a.m[0];i>=1;i--) { left=left*10+a.m[i]; res.m[i]=left/b; left%=b; } while(res.m[res.m[0]]==0&&res.m[0]>1) res.m[0]--; return res; } M pow(M a,int n) { M res; memset(res.m,0,sizeof(res.m)); res.m[0]=res.m[1]=1; M x=a; while(1) { if(n&1) { M tmp; tmp=Mult(res,x); res=tmp; } if(n>>=1) { M tmp; tmp=Mult(x,x); x=tmp; } else break; } return res; } int main() { while(scanf("%d%d",&n,&cou)!=EOF) { M c; int i; memset(c.m,0,sizeof(c.m)); while(cou) { c.m[++c.m[0]]=cou%10; cou/=10; } M rot,ref; int num1=0; if(n&1) { int t=n; while(t>1) { num1+=(t-1); t-=2; } M k; M tt; M q,qq,qqq,qqqq; k=pow(c,num1); tt=Mult(c,k); q=Mult(k,k); qqq=Mult(q,q); qq=Mult(c,q); qqqq=Mult(c,qqq); rot=Add(Add(Add(tt,tt),qq),qqqq); } else { num1=n*n/4; M k; //memset(k.m,0,sizeof(k.m)); k=pow(c,num1); M q,qq; q=Mult(k,k); qq=Mult(q,q); rot=Add(Add(Add(k,k),q),qq); } if(n&1) { M cn; memset(cn.m,0,sizeof(cn.m)); cn.m[0]=1; cn.m[1]=4; ref=Mult(cn,pow(c,(n+1)*n/2)); } else { M an; an=pow(c,(n+1)*n/2); M bn; bn=pow(c,n*n/2); ref=Add(Add(an,an),Add(bn,bn)); } M Final; Final=Div(Add(ref,rot),8); for(i=Final.m[0];i>=1;i--) printf("%d",Final.m[i]); printf("\n"); } return 0; }
|