[hdu 5950 Recursive sequence] 矩阵快速幂

来源:互联网 发布:淘宝刷评价兼职 编辑:程序博客网 时间:2024/05/29 13:23

[hdu 5950 Recursive sequence] 矩阵快速幂

题目链接:[hdu 5950 Recursive sequence]
题意描述:已知通项公式Fi=Fi1+2Fi2+i4, 并且已知F1=a,F2=b和一个数字n,求Fn%2147493647(1n,a,b<231)
解题思路
显然的矩阵快速幂。
需要维护的值有Fi1,Fi2,n4,n3,n2,n,1这七个变量。维护红色变量的原因是方便求出(n+1)4
然后构造矩阵就可以了。

#include <bits/stdc++.h>using namespace std;typedef __int64 LL;const LL MOD = 2147493647;LL T, N, A, B;struct Mat {    static const int MSZ = 7;    LL m[MSZ][MSZ];    void O() { memset(m, 0, sizeof(m)); }    void E() {        O();        for(int i = 0; i < MSZ; i++) m[i][i] = 1;    }    void assign(LL ar[MSZ][MSZ]) {        for(int i = 0; i < MSZ; i++) {            for(int j = 0; j < MSZ; j++) {                m[i][j] = ar[i][j];            }        }    }    Mat operator * (const Mat& e) const {        Mat ret; ret.O();        for(int k = 0; k < MSZ; k++) {            for(int i = 0; i < MSZ; i++) {                if(m[i][k] == 0) continue;                for(int j = 0; j < MSZ; j++) {                    ret.m[i][j] += m[i][k] * e.m[k][j] % MOD;                    ret.m[i][j] %= MOD;                }            }        }        return ret;    }    Mat operator ^ (LL b) const {        Mat ret, a(*this); ret.E();        while(b > 0) {            if(b & 1) ret = ret * a;            a = a * a;            b >>= 1;        }        return ret;    }} tras, init, res;int main() {//    freopen("input.txt", "r", stdin);    // 变换矩阵    LL x[][Mat::MSZ] = {        {1, 2, 1, 0, 0, 0, 0},        {1, 0, 0, 0, 0, 0, 0},        {0, 0, 1, 4, 6, 4, 1},        {0, 0, 0, 1, 3, 3, 1},        {0, 0, 0, 0, 1, 2, 1},        {0, 0, 0, 0, 0, 1, 1},        {0, 0, 0, 0, 0, 0, 1}    };    tras.assign(x);    cin >> T;    while(T --) {        cin >> N >> A >> B;        if(N == 1) {            cout << A % MOD << "\n";            continue;        }        if(N == 2) {            cout << B % MOD << "\n";            continue;        }        // 初始矩阵        LL y[][Mat::MSZ] = {            {B, 0, 0, 0, 0, 0, 0},            {A, 0, 0, 0, 0, 0, 0},            {81, 0, 0, 0, 0, 0, 0},            {27, 0, 0, 0, 0, 0, 0},            {9, 0, 0, 0, 0, 0, 0},            {3, 0, 0, 0, 0, 0, 0},            {1, 0, 0, 0, 0, 0, 0}        };        init.assign(y);        res = tras ^ (N - 2);        res = res * init;        cout << res.m[0][0] << endl;    }    return 0;}
1 0
原创粉丝点击