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:

HOJ 2930 Perfect Fill IIl 线性递推_第1张图片

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:

HOJ 2930 Perfect Fill IIl 线性递推_第2张图片

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

HOJ 2930 Perfect Fill IIl 线性递推_第3张图片

 

#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;
}

  

 

你可能感兴趣的:(OJ)