HOJ 2930 Perfect Fill IIl 线性递推
http://acm.hit.edu.cn/hoj/problem/view?id=2930
Perfect Fill II
Source : ACMGroup | |||
Time limit : 1 sec | Memory limit : 64 M |
Submitted : 69, Accepted : 50
Here comes the Perfect Fill Problem again!
You have tow types of blocks, one is made up of two 1*1 blocks, another is made up of three 1*1 blocks. You can see the shape of two kinds of blocks in the picture below:
Now here comes the problem: How many ways can you fully fill a 2*n block with the two kinds of blocks? Here is one way to fully fill a 2*11 block:
Input specifications
On each line of input, there will be one positive integer n(1 <= n <= 1000000000). Input is End of File.
Output specifications
On each single line, output a number m mod 2010, m is the number of ways to fully fill a 2*n block.
Sample Input
1 2 5 32
Sample Output
1 2 24 596
#include <set> #include <map> #include <cmath> #include <queue> #include <stack> #include <string> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; #define debug puts("here") #define rep(i,n) for(int i=0;i<n;i++) #define foreach(i,vec) for(unsigned i=0;i<vec.size();i++) #define pb push_back const int MOD = 2010; const int X = 5; class Matrix{ public: int n,m; int a[X][X]; Matrix(){ memset(a,0,sizeof(a)); } Matrix(int _n,int _m):n(_n),m(_m){ memset(a,0,sizeof(a)); } Matrix operator * (Matrix p){ int q = p.m; Matrix c(n,q); for(int i=0;i<n;i++) for(int j=0;j<q;j++) for(int k=0;k<m;k++) c.a[i][j] = (c.a[i][j]+a[i][k]*p.a[k][j])%MOD; return c; } void getE(){ memset(a,0,sizeof(a)); for(int i=0;i<n;i++) a[i][i] = 1; } Matrix bin(int exp){ Matrix temp(n,n); temp.getE(); Matrix cur = *this; while(exp>0){ if(exp&1) temp = temp*cur; cur = cur*cur; exp = exp >> 1; } return temp; } void di(){ for(int i=0;i<n;i++){ for(int j=0;j<m;j++) cout<<a[i][j]<<" "; cout<<endl; } cout<<endl; } }; int main(){ #ifndef ONLINE_JUDGE freopen("sum.in","r",stdin); #endif int n; Matrix p = Matrix(3,1); p.a[0][0] = 1; p.a[1][0] = 2; p.a[2][0] = 5; while(~scanf("%d",&n)){ if(n<=3){ printf("%d\n",p.a[n-1][0]); continue; } Matrix ans = Matrix(3,3); ans.a[0][1] = ans.a[1][2] = 1; ans.a[2][0] = 1; ans.a[2][1] = 0; ans.a[2][2] = 2; ans = ans.bin(n-3); ans = ans*p; printf("%d\n",ans.a[2][0]); } return 0; }