zoukankan      html  css  js  c++  java
  • 2018年湘潭大学程序设计竞赛G又见斐波那契(矩阵快速幂)

    题意

    题目链接

    Sol

    直接矩阵快速幂

    推出来的矩阵应该长这样

    egin{equation*}
    egin{bmatrix}
    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{bmatrix}^{i - 1}*
    egin{bmatrix}
    F_{1}\
    F_0\
    1\
    1\
    1\
    1
    end{bmatrix}=
    egin{bmatrix}
    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{bmatrix}*
    egin{bmatrix}
    F_{i - 1}\
    F_{i - 2}\
    i^3\
    i^2\
    i\
    1
    end{bmatrix}=
    egin{bmatrix}
    F_{i}\
    F_{i - 1}\
    (i + 1)^3\
    (i + 1)^2\
    i + 1\
    1
    end{bmatrix}
    end{equation*}

    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #define Pair pair<int, int> 
    #define MP(x, y) make_pair(x, y)
    #define fi first
    #define se second
    #define LL long long
    //#define int long long  
    using namespace std;
    const int mod = 1e9 + 7;
    inline LL read() {
        char c = getchar(); LL x = 0, f = 1;
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    int T;
    LL N;
    struct Matrix {
        LL a[10][10], N;
        Matrix() {
            N = 6;
            memset(a, 0, sizeof(a));
        }
        Matrix operator * (const Matrix &rhs) const {
            Matrix ans;
            for(int k = 1; k <= N; k++) 
                for(int i = 1; i <= N; i++)
                    for(int j = 1; j <= N; j++) 
                        (ans.a[i][j] += (1ll * a[i][k] * rhs.a[k][j]) % mod) %= mod;
            return ans;
        }
    };
    Matrix fp(Matrix a, LL p) {
        Matrix base;
      //  printf("%d", base.a[0][1]);
        for(int i = 1; i <= 6; i++) base.a[i][i] = 1;
        while(p) {
            if(p & 1) base = base * a;
            a = a * a; p >>= 1;
        }
        return base;
    }
    const LL GG[10][10] = {
           {0, 0, 0, 0, 0, 0, 0},
           {0, 1, 1, 1, 1, 1, 1},
           {0, 1, 0, 0, 0, 0, 0},
           {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}
    };
    int main() {
        T = read();
        while(T--) {
            N = read();
            if(N == 1) {puts("1"); continue;}
            if(N == 2) {puts("16"); continue;}
            Matrix M;
            memcpy(M.a, GG, sizeof(M.a));
            Matrix ans = fp(M, N - 2);
            LL out = 0;
            (out += ans.a[1][1] * 16) %= mod;
            (out += ans.a[1][2] * 1) %= mod;
            (out += ans.a[1][3] * 27) %= mod;
            (out += ans.a[1][4] * 9) %= mod;
            (out += ans.a[1][5] * 3) %= mod;
            (out += ans.a[1][6]) %= mod;
            printf("%lld
    ", out % mod);
        }
        return 0;
    }
    /*
    5
    4
    1
    2
    3
    100
    */
  • 相关阅读:
    【Android 工具类】经常使用工具类(方法)大全
    driver: Linux设备模型之input子系统具体解释
    ural 1057 Amount of degrees 【数位dp】
    Java8 Lambda表达式教程
    Java线程池
    NodeJS实战——创建基础应用并应用模板引擎
    【网络】代理服务器
    【HTTP】Wireshark过滤规则
    【HTTP】WireShark中获取Content-Encoding: gzip时的响应内容
    【python】判断字符串日期是否有效
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/9632625.html
Copyright © 2011-2022 走看看