又见斐波那契 矩阵快速幂 线性代数 转移矩阵构造

https://www.nowcoder.com/acm/contest/105/G

题意 :这是一个加强版的斐波那契数列。

给定递推式求F(n)的值(n<1e18),由于这个值可能太大,请对1e9+7取模。

 题解:线性代数题。矩阵快速幂

仿照斐波那契的快速幂模板。

算出F(i)与F(i+1)之间相差的的系数矩阵。

$egin{pmatrix}
1 & 1 & 1 & 1 & 1 & 1\
1 & 0 & 0 & 0 & 0 & 0\
0 & 0 & 1 & 3 & 3 & 1\
0 & 0 & 0 & 1 & 2 & 1\
0 & 0 & 0 & 0 & 1 & 1\
0 & 0 & 0 & 0 & 0 & 1
end{pmatrix}egin{pmatrix}
F_{i-1}\
F_{i-2}\
i^{3}\
i^{2}\
i\
1
end{pmatrix} =egin{pmatrix}
F_{i-1} +F_{i-2} +i^{3} +i^{2} +i+1\
F_{i-1}\
i^{3} +3i^{2} +3i+1\
i^{2} +2i+1\
i+1\
1
end{pmatrix}$

(好像看的人挺多的,贴一发公式)

然后对系数矩阵快速幂,直接用模板。

#define _CRT_SECURE_NO_WARNINGS
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<cmath>
#include<cstdio>
#include<string>
#include<stack>
#include<ctime>
#include<list>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<sstream>
#include<iostream>
#include<functional>
#include<algorithm>
#include<memory.h>
//#define INF 0x3f3f3f3f
#define eps 1e-6
#define pi acos(-1.0)
#define e exp(1.0)
#define rep(i,t,n)  for(int i =(t);i<=(n);++i)
#define per(i,n,t)  for(int i =(n);i>=(t);--i)
#define mp make_pair
#define pb push_back
#define mmm(a,b) memset(a,b,sizeof(a))
//std::ios::sync_with_stdio(false);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
void smain();
#define ONLINE_JUDGE
int main() {
    ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    long _begin_time = clock();
#endif
    smain();
#ifndef ONLINE_JUDGE
    long _end_time = clock();
    printf("time = %ld ms.", _end_time - _begin_time);
#endif
    return 0;
}
const int maxn = 4e5 + 100;
const ll mod = 1e9 + 7;
const ll INF = (100000)*(200000ll) + 1000;

ll n, m;
struct matrix {
    ll ma[8][8];
    void clear() {
        mmm(ma, 0);
        rep(i, 1, 6)ma[i][i] = 1;
    }
    void print() {
        rep(i, 1, 6) {
            rep(j, 1, 6) {
                cout << ma[i][j] << ' ';
            }cout << endl;
        }
    }
    matrix mul(matrix a) {
        matrix ans;
        mmm(ans.ma, 0);
        rep(i,1,6)
            rep(j,1,6)
            rep(k, 1, 6) {
            ans.ma[i][j] += ma[i][k] * a.ma[k][j];
            ans.ma[i][j] %= mod;
        }
        return ans;
    }
    matrix mul(ll a[][8]) {
        matrix ans;
        mmm(ans.ma, 0);
        rep(i, 1, 6)
            rep(j, 1, 6)
            rep(k, 1, 6) {
            ans.ma[i][j] = (ans.ma[i][j] +ma[i][k] * a[k][j])%mod;
            //ans.ma[i][j] %= mod;
        }
        return ans;
    }
    matrix quick(ll n) {
        matrix ans,a=*this;

        ans.clear();
        while (n) {
            if (n& 1) {
                ans=ans.mul(a);
                
            }
            n >>= 1;
            a=a.mul(a);
        }
        return ans;
    }
    
};
void up(ll &ans, ll t) {
    ans =(ans+t)%mod;
}

void Run() {

}


void smain() {
    ll  res[8][8]; mmm(res,0);
    rep(i, 1, 6) res[1][i] = 1;
    res[2][1] = 1;
    res[3][3] = 1;
    res[3][4] = res[3][5] = 3;
    res[3][6] = 1;
    res[4][4] =res[4][6]= 1;
    res[4][5] = 2;
    res[5][5] = res[5][6] =res[6][6]= 1;
    int t; cin >> t;
    while (t--) {
        cin >> n;
        matrix ans;
        ans.clear();

        ans=ans.mul(res);
        //ans.print();

        ans = ans.quick(n-1);
        //ans.print();
        //ans.ma = res;

        ll x=0;
        up(x, ans.ma[1][1]);
        //up(x, ans.ma[1][2]);
        up(x, ans.ma[1][3] * 8%mod);
        up(x, ans.ma[1][4] * 4%mod);
        up(x, ans.ma[1][5] * 2%mod);
        up(x, ans.ma[1][6]);
        cout << x%mod << endl;
    }

}

成功的路并不拥挤,因为大部分人都在颓(笑)
原文地址:https://www.cnblogs.com/SuuT/p/8963570.html