Poj 3420 Quad Tiling-type dp, pojtiling
Question:
For a large rectangle of 4 * n (n <10 ^ 9), ask how many solutions are there to fill with a small rectangle of 1*2.
Analysis:
Tile laying again, But n is too big this time, and no more one grid of dp. You can first calculate the State transfer of the adjacent two rows, and then use the Matrix to accelerate the State transfer of n rows.
Code:
//poj 3420//sep9#include <iostream>using namespace std;const int maxN=16;struct MATRIX{__int64 m[maxN][maxN];}mat;int n,mod;void dfs(int l,int now,int pre){if(l>4) return;if(l==4){++mat.m[pre][now];return ;}dfs(l+1,(now<<1)|1,pre<<1);dfs(l+1,now<<1,(pre<<1)|1);dfs(l+2,(now<<2)|3,(pre<<2)|3);}MATRIX mul(MATRIX a,MATRIX b) { MATRIX c; memset(c.m,0,sizeof(c.m)); for(int i=0;i<16;++i) for(int j=0;j<16;++j) for(int k=0;k<16;++k){ c.m[i][j]+=a.m[i][k]*b.m[k][j]; c.m[i][j]%=mod;}return c; }MATRIX expo(MATRIX a,int k) { if(k==1)return a; MATRIX e; memset(e.m,0,sizeof(e.m)); for(int i=0;i<16;++i){e.m[i][i]=1;} if(k==0)return e; while(k) { if(k&1)e=mul(a,e); a=mul(a,a); k>>=1; } return e; } int main() { memset(mat.m,0,sizeof(mat.m)); dfs(0,0,0); while(~scanf("%d%d",&n,&mod)) { if(!n&&!mod)break; if(mod==1){printf("0\n");continue;} MATRIX ans=expo(mat,n); printf("%I64d\n",ans.m[15][15]); } return 0; }