LATGACH4 - tacongnam/DylanHarris GitHub Wiki

  • Problem: VNSPOJ - LATGACH4
  • Tag: Matrix, DP

Table of Contents

Content

Cho một hình chữ nhật kích thước 2xN (1<=N<10^9). Hãy đếm số cách lát các viên gạch nhỏ kích thước 1x2 và 2x1 vào hình trên sao cho không có phần nào của các viên gạch nhỏ thừa ra ngoài, cũng không có vùng diện tích nào của hình chữ nhật không được lát.

Input:

Gồm nhiều test, dòng đầu ghi số lượng test T ( T<=100 ). T dòng sau mỗi dòng ghi một số N.

Output:

Ghi ra T dòng là số cách lát tương ứng lấy phần dư cho 111539786.

Example:

Input:

 3
 1
 2
 3

Output:

 1
 2
 3

Solution:

Xem lại bài LATGACH về công thức.
Để tính nhanh được số Fibonacci số thứ 10^9, ta cần dùng phép nhân ma trận.

Code:

    #include <bits/stdc++.h>
    #define ll long long
    #define mod 111539786
    using namespace std;
    struct matrix
    {
        ll val[10][10];
        ll row, col;
    };
    matrix operator * (matrix a, matrix b)
    {
        matrix res;
        for(ll i = 1; i <= a.row; i++)
            for(ll j = 1; j <= b.col; j++)
            {
                res.val[i][j] = 0;
                for(ll k = 1; k <= a.col; k++)
                       res.val[i][j] = (res.val[i][j] + a.val[i][k] * b.val[k][j])%mod;
            }
        res.row = a.row; res.col = b.col;
        return res;
    }
    matrix mu (matrix a, ll b)
    {
        if(b == 1)
            return a;
        matrix x = mu(a,(b/2));
        if(b % 2 == 1)
            return (x * x) * a;
        else
            return x * x;
    }
    matrix a,b,c,d;
    ll f,t;
    int main()
    {
        cin>>t;
        a.row = 2, a.col = 2;
        a.val[1][1] = 1, a.val[1][2] = 1;
        a.val[2][1] = 1, a.val[2][2] = 0;
        b.row = 2, b.col = 1;
        b.val[1][1] = 1, b.val[2][1] = 1;
        while(t--)
        {
            cin>>f;
            c = mu(a,f);
            d = c * b;
            cout<<d.val[2][1]<<endl;
        }
        return 0;
    }
⚠️ **GitHub.com Fallback** ⚠️