舉火燎天
問題描述
徵夷王將越南(南夷)攻下來之後,決定用
這
爲了顯示我們中華文化的博大精深,徵夷王決定,相鄰的火炬的顏色不能相同。
現在徵夷王想知道,滿足他要求的方案有多少個。
由於火炬的位置已經固定,所以即便旋轉翻轉之後兩種方案相同也視作不同方案。
輸入
輸入文件名爲Lights.in。
輸入一行兩個正整數
輸出
輸出文件名爲Lights.out。
輸出一行一個正整數,代表方案總數。
輸入樣例
3 4
輸出樣例
24
數據範圍
對於
Solution
設
Code
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define LL long long
#define MOD 100000000
#define Max(x,y) ((x)>(y)?(x):(y))
struct bign{
LL s[100],len;
bign(){
memset(s,0,sizeof s);
len=1;
}
bign operator = (const LL num){
s[1]=num;len=1;
return *this;
}
bign operator * (const LL num){
bign c;c.len=len+1;
for(LL i=1;i<=len;i++){
c.s[i+1]=(c.s[i]+s[i]*num)/MOD;
c.s[i]=(c.s[i]+s[i]*num)%MOD;
}
while(!c.s[c.len]&&c.len>1)c.len--;
return c;
}
bign operator + (const bign &num){
bign c;c.len=Max(len,num.len);
for(LL i=1;i<=c.len;i++){
c.s[i+1]=(c.s[i]+s[i]+num.s[i])/MOD;
c.s[i]=(c.s[i]+s[i]+num.s[i])%MOD;
}
if(c.s[c.len+1])c.len++;
return c;
}
void out(){
for(LL i=len;i>=1;i--){
if(len==i)printf("%lld",s[len]);
else printf("%08lld",s[i]);
}
}
};
LL n,m;
bign f[110][2];
int main(){
freopen("Lights.in","r",stdin);
freopen("Lights.out","w",stdout);
scanf("%lld%lld",&n,&m);
if(n==1){
printf("%lld\n",m);
return 0;
}
else if(n==2){
LL ans=m*(m-1);
printf("%lld\n",ans);
return 0;
}
else{
f[1][1]=m;f[0][0]=0;
for(int i=2;i<=n;i++){
f[i][1]=f[i-1][0];
f[i][0]=f[i-1][0]*(m-2)+f[i-1][1]*(m-1);
}
f[n][0].out();
}
return 0;
}