• 2018年湘潭大学程序设计竞赛 G又见斐波那契


    题目描述 

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

    输入描述:

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

    输出描述:

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

    输入

    4
    1
    2
    3
    100

    输出

    1
    16
    57
    558616258

    一开始不了解矩阵快速幂,不知道怎么做,刷了一波矩阵快速幂再做这个就发现很简单了。

    很明显就是6*6矩阵,构建好矩阵就行了。构建矩阵如下:

      fi        1    1    1    1    1    1    fi-1

     fi-1     1      0     0    0    0   0    fi-2

    (i+1)3     0      0      1    3    3    1    i3

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

    (i+1)      0      0      0    0    1    1    i

      1        0      0      0    0    0    1    1

     1 #include <bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int mod = 1000000007;
     5 struct mat {
     6     ll m[6][6];
     7     mat() {
     8         memset(m, 0, sizeof(m));
     9     }
    10 };
    11 
    12 mat mul(mat &A, mat &B) {
    13     mat C;
    14     for(int i = 0; i < 6; i ++) {
    15         for(int j = 0; j < 6; j ++) {
    16             for(int k = 0; k < 6; k ++) {
    17                 C.m[i][j] = (C.m[i][j] + A.m[i][k]*B.m[k][j]) %mod;
    18             }
    19         }
    20     }
    21     return C;
    22 }
    23 
    24 
    25 mat pow(mat A, ll n) {
    26     mat B;
    27     for(int i = 0; i < 6; i ++) B.m[i][i] = 1;
    28     while(n) {
    29         if(n&1LL) B = mul(B, A);
    30         A = mul(A, A);
    31         n >>= 1;
    32     }
    33     return B;
    34 }
    35 int main() {
    36     int t;
    37     cin >> t;
    38     mat A;
    39     for(int i = 0; i < 6; i ++) A.m[0][i] = 1;
    40     A.m[1][0] = A.m[2][2] = A.m[2][5] = 1;
    41     A.m[3][3] = A.m[3][5] = A.m[4][4] = 1;
    42     A.m[4][5] = A.m[5][5] = 1;
    43     A.m[2][3] = A.m[2][4] = 3;
    44     A.m[3][4] = 2;
    45     while(t--) {
    46         ll n;
    47         cin >> n;
    48         mat B =pow(A, n-1);
    49         ll ans = B.m[0][0]+B.m[0][2]*8+B.m[0][3]*4+B.m[0][4]*2+B.m[0][5];
    50         cout << ans%mod << endl;
    51     }
    52     return 0;
    53 }
  • 相关阅读:
    定时器实现点击重新发送信息倒计时显示
    新浪微博5s钟后跳转页面
    时钟制作代码
    判断线段相交
    POJ1265:Area(多边形面积公式+pick公式) 好题
    ACM零散知识
    POJ2318:TOYS(叉积判断点和线段的关系+二分)&&POJ2398Toy Storage
    计算几何初步认识
    UVA10026:Shoemaker's Problem(贪心)
    UVA10020:Minimal coverage(最小区间覆盖)
  • 原文地址:https://www.cnblogs.com/xingkongyihao/p/9017138.html
Copyright © 2020-2023  润新知