zoukankan      html  css  js  c++  java
  • 矩阵快速幂

    链接:https://www.nowcoder.com/acm/contest/105/G
    来源:牛客网

    题目描述

    这是一个加强版的斐波那契数列。
    给定递推式
    求F(n)的值,由于这个值可能太大,请对109+7取模。

    输入描述:

    第一行是一个整数T(1 ≤ T ≤ 1000),表示样例的个数。
    以后每个样例一行,是一个整数n(1 ≤ n ≤ 10
    18
    )。

    输出描述:

    每个样例输出一行,一个整数,表示F(n) mod 1000000007。
    示例1

    输入

    4
    1
    2
    3
    100

    输出

    1
    16
    57
    558616258

    题意 : 一个比较裸的题,只要构造出来矩阵就很容易。


    代码示例 :
    #define ll long long
    const ll maxn = 1e6+5;
    const ll mod = 1000000007;
    const double eps = 1e-9;
    const double pi = acos(-1.0);
    const ll inf = 0x3f3f3f3f;
    
    ll n;
    struct mat
    {
        ll a[10][10];
    };
    const ll modulu[10][10] = {
        {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}
    };
    
    mat mul(mat a, mat b){
        mat r;
        memset(r.a, 0, sizeof(r.a));
        
        for(ll i = 0; i < 6; i++){
            for(ll j = 0; j < 6; j++){
                for(ll k = 0; k < 6; k++){
                    r.a[i][j] += (a.a[i][k]*b.a[k][j])%mod;
                    r.a[i][j] %= mod;            
                }
            }
        }
        return r;
    }
    
    mat qpow(mat a, ll x){
        mat b;
        memset(b.a, 0, sizeof(b.a));
        for(ll i = 0; i <6; i++) b.a[i][i] = 1;
        
        while(x){
            if (x&1) b = mul(b, a);
            a = mul(a, a);
            x >>= 1;
        }
        return b;
    }
    
    int main() {
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
        ll t;
        
        cin >> t;
        while(t--){
            scanf("%lld", &n);
            mat a;
            memcpy(a.a, modulu, sizeof(modulu));
            if (n == 1) {printf("1
    "); continue;}
            else if (n == 0) {printf("0
    "); continue;} 
            //for(ll i = 0; i < 6; i++){
                //for(ll j = 0; j < 6; j++){
                    //prllf("%d ", a.a[i][j]);
                //}
                //prllf("
    ");
            //}
            a = qpow(a, n-1);
            ll sum = a.a[0][0]+a.a[0][2]*8+a.a[0][3]*4+a.a[0][4]*2+a.a[0][5];
            printf("%lld
    ", sum%mod);
        }
        return 0;
    }
    
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    C# 计算结果四舍五入
    同时执行多条SQL语句
    将一个datatable的值赋给另一个dt的三种方法转
    Oracle中增加、删除、修改字段
    Oracle 某列转为行
    DataList中链接跳转页面传参数
    修改数据库中多个表中的同一个字段的长度(可参照修改成同一字段的列名、注释等)
    克隆表结构
    博客专题
    Rational Rose2003 安装教程
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/8973800.html
Copyright © 2011-2022 走看看