• wmjxoj


    题目传送门

    矩阵加快速幂运算才发现这么好用。

    根据递推公式f(i+1) = fi + (i+1)*(i+1) + (i+1)构造矩阵

    | f(i) + (i+1)*(i+1) + (i+1) |                  | 1    1    1    0 |        |      f(1)      |

    |       (i + 2)*(i + 2)           |       =         | 0    1    2    1 |   *   | (i+1)*(i+1) |

    |              i + 2                 |                  | 0     0    1    1|        |     i + 1      |

    |                 1                   |                  | 0     0    0    1|        |        1        |

    就ok了。

    #include <map>
    #include <set>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <iostream>
    #include <stack>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <cstdlib>
    //#include <bits/stdc++.h>
    //#define LOACL
    #define space " "
    using namespace std;
    typedef long long LL;
    //typedef __int64 Int;
    typedef pair<int, int> paii;
    const int INF = 0x3f3f3f3f;
    const double ESP = 1e-5;
    const double PI = acos(-1.0);
    const int MOD = 1e9 + 7;
    const int MAXN = 15;
    int n, m;
    struct Matrix {
        LL m[MAXN][MAXN];
        int row, col;
    };
    Matrix ori, res;
    void init() {
        ori.m[2][4] = ori.m[3][3] = ori.m[3][4] = ori.m[4][4] = 1;
        ori.m[1][1] = ori.m[1][2] = ori.m[1][3] = ori.m[2][2] = 1;
        ori.m[1][4] = ori.m[2][1] = ori.m[3][1] = 0; ori.m[2][3] = 2;
        ori.m[3][2] = ori.m[4][1] = ori.m[4][2] = ori.m[4][3] = 0;
        ori.col = ori.row = 4;
    }
    Matrix multi(Matrix x, Matrix y) {
        Matrix z;
        memset(z.m, 0, sizeof(z.m));
        z.row = x.row; z.col = y.col;
        for (int i = 1; i <= x.row; i++) {
            for (int k = 1; k <= x.col; k++) {
                for (int j = 1; j <= y.col; j++) {
                    z.m[i][j] += x.m[i][k]*y.m[k][j]%MOD;
                }
                z.m[i][k] %= MOD;
            }
        }
        return z;
    }
    Matrix pow_mod(Matrix a, LL x){
        Matrix b;
        b.col = a.col; b.row = a.row;
        memset(b.m, 0, sizeof(b.m));
        for (int i = 1; i <= 4; i++) {
            b.m[i][i] = 1;
        }
        while(x){
            if(x&1) b = multi(a,b);
            a = multi(a, a);
            x >>= 1;
        }
        return b;
    }
    int main() {
        int T;
        init();
        LL f, n;
        scanf("%d", &T);
        while (T--) {
            scanf("%lld%lld", &f, &n);
            res = pow_mod(ori, n - 1);
            LL ans = (f*res.m[1][1]%MOD + 4*res.m[1][2]%MOD + 2*res.m[1][3]%MOD + res.m[1][4]%MOD)%MOD;
            printf("%lld
    ", ans);
        }
        return 0;
    }


      

  • 相关阅读:
    Ubuntu终端Terminal常用快捷键
    继承(一)
    c语言中动态数组的建立
    指针的一些小的知识点
    什么是内存地址
    组合(composition)与继承(inheritance)
    重载new和delete
    不要轻易delete void*指针,这样会隐藏比较多的错误。
    内存管理运算符new delete与内存管理函数malloc free的区别——已经他们对对象创建的过程。
    自动类型转换之全局重载运算符与成员重载运算符
  • 原文地址:https://www.cnblogs.com/cniwoq/p/6770757.html
Copyright © 2020-2023  润新知