Light OJ 1096 nth Term (矩陣快速冪)

題目鏈接:http://www.lightoj.com/volume_showproblem.php?problem=1096


遞推矩陣如下:



代碼如下:

#include <cstdio>
#include <cstring>

const int mod = 10007;
const int matSize = 5;
int n, a, b, c;

struct Mat
{
    int val[matSize][matSize];
    void init() { memset(val,0,sizeof(val)); }
    void set1() {                             // 把矩陣置爲單位矩陣
        for(int i=0; i<matSize; i++)
            for(int j=0; j<matSize; j++)
                val[i][j] = (i == j);
    }
    friend Mat operator*(Mat a, Mat b)        // 重載*號進行矩陣乘法
    {
        Mat res;
        res.init();
        for(int i=0; i<matSize; i++) {
            for(int k=0; k<matSize; k++) {
                if(a.val[i][k]) {
                    for(int j=0; j<matSize; j++) {
                        res.val[i][j] += a.val[i][k]*b.val[k][j];
                        res.val[i][j] %= mod;
                    }
                }
            }
        }
        return res;
    }
    friend Mat operator^(Mat a, int x)         // 重載^號進行快速冪運算
    {
        Mat res;
        res.set1();
        while(x)
        {
            if(x & 1) res = res * a;
            a = a * a;
            x >>= 1;
        }
        return res;
    }
};

Mat base;
Mat A;
Mat B;

void init()
{
    base.val[3][0] = 1;
}

void init1()
{
    A.val[0][0] = a;
    A.val[0][2] = b;
    A.val[0][3] = c;
    A.val[1][0] = 1;
    A.val[2][1] = 1;
    A.val[3][3] = 1;
}

int main()
{
    int cases;
    scanf("%d", &cases);
    for(int t=1; t<=cases; t++) {
        scanf("%d%d%d%d", &n, &a, &b, &c);
        base.init();
        init();
        A.init();
        init1();
        B = (A^n) * base;
        printf("Case %d: %d\n", t, B.val[2][0]);
    }
    return 0;
}


發佈了40 篇原創文章 · 獲贊 4 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章