zoukankan      html  css  js  c++  java
  • [矩阵快速幂] 数列(类斐波那契

    数列

    题目描述

    a[1]=a[2]=a[3]=1

    a[x]=a[x-3]+a[x-1]  
    求a数列的第n项对1000000007(10^9+7)取余的值。

    输入

    第一行一个整数T,表示询问个数。

    以下T行,每行一个正整数n。

    输出

    每行输出一个非负整数表示答案。

    样例输入

    3
    6
    8
    10

    样例输出

    4
    9
    19

    提示

    对于30%的数据 n<=100;


    对于60%的数据 n<=2*10^7;


    对于100%的数据 T<=100,n<=2*10^9;

     

     

    emmm基本就是一道矩阵快速幂的裸题,根据题目需要自己求得矩阵套进去即可

    (顺便一提,学校OJ里输出1的情况没有换行竟然只有18分orz  调试了半天不知道错在哪里

     下面放上代码

     

     1 #include<cstdio>
     2 #include<cstring>
     3  
     4 const int Mod = 1e9 + 7; 
     5  
     6 struct Matrix {
     7     long long m[3][3]; 
     8 }; 
     9  
    10 Matrix Mult(Matrix a, Matrix b) {
    11     long long sums = 0; 
    12     Matrix c; 
    13     memset(c.m, 0, sizeof(c.m)); 
    14     for (int i = 0; i <= 2; i++) {
    15         for (int j = 0; j <= 2; j++) {
    16             sums = 0; 
    17             for (int k = 0; k <= 2; k++) {
    18                 sums = (sums + a.m[i][k] * b.m[k][j]) % Mod; 
    19             }
    20             c.m[i][j] = sums; 
    21         }
    22     }
    23     return c; 
    24 }
    25  
    26 Matrix Qpow(Matrix a, int k) {
    27     Matrix res;
    28     memset(res.m, 0, sizeof(res.m));
    29     for (int i = 0; i <= 2; i++) {
    30         res.m[i][i] = 1; 
    31     } 
    32     while(k) {
    33         if (k & 1) {
    34             res = Mult(res, a); 
    35         }
    36         a = Mult(a, a); 
    37         k = (k >> 1); 
    38     }
    39     return res; 
    40 }
    41  
    42 int main() {
    43     long long n; 
    44     int t; 
    45     scanf("%d", &t); 
    46     for (int cnt = 1; cnt <= t; cnt++) {
    47         Matrix A, B; 
    48         memset(A.m, 0, sizeof(A.m)); 
    49         memset(B.m, 0, sizeof(B.m)); 
    50         scanf("%lld", &n); 
    51         if (n <= 3) {
    52             printf("1
    "); 
    53             continue; 
    54         }
    55         for (int i = 0; i < 3; i++) {
    56             A.m[i][i + 1] = 1; 
    57         }
    58         A.m[2][0] = 1;
    59         A.m[2][2] = 1; 
    60         for (int i = 0; i < 3; i++) {
    61             B.m[i][0] = 1; 
    62         }
    63         A = Qpow(A, n - 3); 
    64         A = Mult(A, B); 
    65         printf("%d
    ", A.m[2][0]); 
    66     }
    67     return 0; 
    68 }

     

     

  • 相关阅读:
    Linux网络相关命令firewalld和netfilter、iptables 使用(6/22)
    Linux时间设置与iptables命令
    负载均衡集群ipvsadm命令及基本用法
    LVS原理详解以及部署
    linux比较两个文件的不同(6/21)
    如何使用sql函数平均值、总数、最小值、最大值
    python中数据类型转换
    使用 getopt 处理命令行长参数
    Mysql常用命令行大全
    C#控制台程序使用Log4net日志组件
  • 原文地址:https://www.cnblogs.com/GldHkkowo/p/8832843.html
Copyright © 2011-2022 走看看