zoukankan      html  css  js  c++  java
  • 又见斐波那契 矩阵快速幂 线性代数 转移矩阵构造

    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;
        }
    
    }
    
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    封装 lhgDialog弹出窗口组件 为C#的api
    最简单的dbhelper类
    asp.net无组件导出Excel
    js中的escape的用法汇总
    【Demo 0110】获取内存信息
    【Demo 0119】延时加载DLL 编程
    【Demo 0112】共享数据段
    【Demo 0116】堆的使用
    【Demo 0111】获取进程当前内存使用
    【Demo 0118】动态加载DLL
  • 原文地址:https://www.cnblogs.com/SuuT/p/8963570.html
Copyright © 2011-2022 走看看