PKU 2440 DNA
http://poj.org/problem?id=2440
0と1をL個並べたときに、101という並びと111という並びを含まない並びの個数を2005で割った余りを求めろと言うな問題。
上手くやれば繰り返し二乗法は必要ないようです。
漸化式を作って動的計画法。周期は200?
vector<vector<int> > mult(const vector<vector<int> >& le,const vector<vector<int> >& ri){ vector<vector<int> > ret(8,vector<int>(8,0)); rep(i,8){ rep(j,8)rep(k,8)ret[i][j]=(ret[i][j]+le[i][k]*ri[k][j])%2005; } return ret; } vector<vector<int> > mat(8,vector<int>(8,0)); vector<vector<int> > pow(int n){ if(n==0){ vector<vector<int> > ret(8,vector<int>(8,0)); rep(i,8)ret[i][i]=1; return ret; } vector<vector<int> > ret=pow(n/2); ret=mult(ret,ret); if(n%2)ret=mult(ret,mat); return ret; } main(){ rep(i,8)mat[i][i/2]=mat[i][i/2+4]=1; mat[2][5]=mat[3][5]=mat[6][7]=mat[7][7]=0; int n; while(cin>>n){ vector<vector<int> >ansm=pow(n%200); int ans=0; rep(i,8)ans+=ansm[0][i]; ans-=ansm[0][5]+ansm[0][7]; cout<<ans%2005<<endl; } }