前兩天看了Polya定理,今天做了一道HDU的題,傷心了,超時。。。我的高精度超時。。。看了statistics,大部分是用JAVA過的。要好好學JAVA。。。
Problem Description
話說就是因為這個游戲,Lele已經變成一個名人,每當他一出現(xiàn)在公共場合,就有無數(shù)人找他簽名,挑戰(zhàn)。 為了防止引起社會的騷動,Lele決定還是乖乖呆在家里。 在 家很無聊,Lele可不想像其他人一樣每天沒事在家數(shù)錢玩,于是他就開始數(shù)棋盤。他想知道,一個有N×N個格子的正方形棋盤,每個格子可以用C種不同顏色 來染色,一共可以得到多少種不同的棋盤。如果一個棋盤,經過任意旋轉,反射后變成另一個棋盤,這兩個棋盤就是屬于同一種棋盤。 比如當N=C=2的時候,有下面六種不同的棋盤

現(xiàn)在告訴你N和C,請你幫幫Lele算算,到底有多少種不同的棋盤
本題目包含多組測試,請?zhí)幚淼轿募Y束。 每組測試數(shù)據(jù)包含兩個正整數(shù)N和C(0<N,C,<31),分別表示棋盤的大小是N×N,用C種顏色來進行染色。
對于每組測試,在一行里輸出答案。
話說這題就是Polya定理,公式:S=(C^M1+C^M2+...+C^Mn)/G G是階數(shù),Mi是各階循環(huán)節(jié)的個數(shù)。 根據(jù)題意,有旋轉和翻轉兩種情況,G=8,旋轉4,翻轉4。 對于旋轉,以2*2為例很容易知道有旋轉90度,180度,270度和360度,循環(huán)分別為(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; }
|