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 }

     

     

  • 相关阅读:
    初试 spring web mvc
    读取网络数据缓存在本地 流程图
    servlet 过滤器实现 请求转发(跳转);跨域转发请求;tomcat 环境下。
    C# .net基于Http实现web server(web服务)
    微信公众平台开发
    Linux目录结构及作用
    MySQL事件调度器event的使用
    MySQL触发器trigger的使用
    存储过程的查、改、删
    MySQL游标的简单实践
  • 原文地址:https://www.cnblogs.com/GldHkkowo/p/8832843.html
Copyright © 2011-2022 走看看