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

現(xiàn)在告訴你N和C,請(qǐng)你幫幫Lele算算,到底有多少種不同的棋盤
本題目包含多組測(cè)試,請(qǐng)?zhí)幚淼轿募Y(jié)束。
每組測(cè)試數(shù)據(jù)包含兩個(gè)正整數(shù)N和C(0<N,C,<31),分別表示棋盤的大小是N×N,用C種顏色來進(jìn)行染色。
對(duì)于每組測(cè)試,在一行里輸出答案。
話說這題就是Polya定理,公式:S=(C^M1+C^M2+...+C^Mn)/G
G是階數(shù),Mi是各階循環(huán)節(jié)的個(gè)數(shù)。
根據(jù)題意,有旋轉(zhuǎn)和翻轉(zhuǎn)兩種情況,G=8,旋轉(zhuǎn)4,翻轉(zhuǎn)4。
對(duì)于旋轉(zhuǎn),以2*2為例很容易知道有旋轉(zhuǎn)90度,180度,270度和360度,循環(huán)分別為(1,2,3,4);(1,3)(2,4);(1,4,3,2);(1)(2)(3)(4).
翻轉(zhuǎn)則是枚舉對(duì)稱軸,正方形又分為沿對(duì)角線和沿邊的中垂線兩種。
附超時(shí)代碼。。。。計(jì)算結(jié)果是正確的。。。。。:

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;
}