PKU 3734-Blocks
問題概要
赤,緑,黄色,青のブロックをN個並べたい.
ただし,赤と緑は偶数個並べたい.
この時並べ方は何通りあるか.
解法
an 赤も緑も偶数個
bn 赤が奇数個
cn 緑が奇数個
dn 赤も緑も奇数個
とすると
a0=1
b0=0
c0=0
d0=0
an=an-1*2+bn-1+cn-1
bn=an-1+2*bn-1+dn-1
cn=an-1+2*cn-1+dn-1
dn=bn-1+cn-1+2*dn-1
が成り立つので繰り返し二乗法を用いる
実装(C++)
#include <vector> #include <iostream> #include <algorithm> using namespace std; typedef vector<int> Array; typedef vector<Array> Matrix; #define REP(i,x)for(int i=0;i<(int)x;i++) const int MOD=10007; Matrix operator*(const Matrix &a,const Matrix &b){ int V=a.size(); Matrix res(V,Array(V,0)); REP(i,V){ REP(j,V){ REP(k,V){ res[i][j]+=a[i][k]*b[k][j]; res[i][j]%=MOD; } } } return res; } Matrix make_E(int V){ Matrix res(V,Array(V,0)); REP(i,V){ res[i][i]=1; } return res; } Matrix operator^(const Matrix &a,int v){ if(v==0)return make_E(a.size()); Matrix res=(a*a)^(v/2); if(v&1)res=res*a; return res; } int main() { int t; cin>>t; while(t--){ int n; cin>>n; Matrix base(4,Array(4)); base[0][0]=2; base[0][1]=1; base[0][2]=1; base[0][3]=0; base[1][0]=1; base[1][1]=2; base[1][2]=0; base[1][3]=1; base[2][0]=1; base[2][1]=0; base[2][2]=2; base[2][3]=1; base[3][0]=0; base[3][1]=1; base[3][2]=1; base[3][3]=2; base=base^n; cout<<base[0][0]<<endl; } return 0; }