zoukankan      html  css  js  c++  java
  • 递推求值【快速幂矩阵】

    递推求值

     
    描述

    给你一个递推公式:

    f(x)=a*f(x-2)+b*f(x-1)+c

    并给你f(1),f(2)的值,请求出f(n)的值,由于f(n)的值可能过大,求出f(n)对1000007取模后的值。

    注意:-1对3取模后等于2

     
    输入
    第一行是一个整数T,表示测试数据的组数(T<=10000)
    随后每行有六个整数,分别表示f(1),f(2),a,b,c,n的值。
    其中0<=f(1),f(2)<100,-100<=a,b,c<=100,1<=n<=100000000 (10^9)
    输出
    输出f(n)对1000007取模后的值
    样例输入
    2
    1 1 1 1 0 5
    1 1 -1 -10 -100 3
    样例输出
    5
    999896

    【分析】由于n的值比较大,所以常规方法肯定会超时。根据递推式求第n个表达式的值时,通常用矩阵乘法来做。

    本题要构造两个矩阵,其中一个为矩阵A,作为初始矩阵

    f2  0   0
    f1  0   0
    1   0   0
    //初始化矩阵arr 
    memset(arr.mat, 0, sizeof(arr.mat));
    arr.mat[0][0] = f2;  arr.mat[1][0] = f1;  arr.mat[2][0] = 1;

    另一个为矩阵B

    b   a   c
    1   0   0
    0   0   1
     //初始化矩阵tmp 
     tmp.mat[0][0] = b;   tmp.mat[0][1] = a;   tmp.mat[0][2] = c;
     tmp.mat[1][0] = tmp.mat[2][2] = 1;
     tmp.mat[1][1] = tmp.mat[1][2] = tmp.mat[2][0] = tmp.mat[2][1] = 0;
    相乘后的结果为
    f2*b+f1*a+1*c    f2*a+0+0        f2*c+0+0
    f1*b+0+0           a*f+0+0          f1*c+0+0
    c*1+0+0            1*a+0+0         1*c+0+0
    (备注:任何矩阵与单位矩阵(n*n)相乘后,不改变原来矩阵的值)
    因为F(2)和F(1)是已知的,当n>=3时,每次都乘以矩阵B,就能推出下一个矩阵。而矩阵的第一行第一列的元素就是所求的结果。

    所以利用矩阵快速幂能够快速准确地求出结果。

     

    AC代码:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #define mod 1000007
     4 #define N 3
     5 typedef long long LL;
     6 struct Matrix
     7 {
     8     LL mat[N][N];
     9 };
    10 
    11 Matrix unit_matrix =
    12 {
    13     1, 0, 0,
    14     0, 1, 0,
    15     0, 0, 1
    16 }; //单位矩阵
    17 
    18 Matrix mul(Matrix a, Matrix b) //矩阵相乘
    19 {
    20     Matrix res;
    21     for(int i = 0; i < N; i++)
    22         for(int j = 0; j < N; j++)
    23         {
    24             res.mat[i][j] = 0;
    25             for(int k = 0; k < N; k++)
    26             {
    27                 res.mat[i][j] += a.mat[i][k] * b.mat[k][j];
    28                 res.mat[i][j] %= mod;
    29             }
    30         }
    31     return res;
    32 }
    33 
    34 Matrix pow_matrix(Matrix a, LL n)//矩阵快速幂
    35 {
    36     Matrix res = unit_matrix;
    37     while(n != 0)
    38     {
    39         if(n & 1)
    40             res = mul(res, a);
    41         a = mul(a, a);
    42         n >>= 1;
    43     }
    44     return res;
    45 }
    46 
    47 int main()
    48 {
    49     LL n, f1, f2, a, b, c, T;
    50     Matrix tmp, arr;
    51     scanf("%lld",&T);
    52     while(T--)
    53     {
    54         scanf("%lld%lld%lld%lld%lld%lld",&f1, &f2, &a, &b, &c, &n);
    55         if(n == 1)
    56             printf("%lld
    ",(f1+mod)%mod);
    57         else if(n == 2)
    58             printf("%lld
    ",(f2+mod)%mod);
    59         else
    60         {
    61             //初始化矩阵arr 
    62             memset(arr.mat, 0, sizeof(arr.mat));
    63             arr.mat[0][0] = f2;  arr.mat[1][0] = f1;  arr.mat[2][0] = 1;
    64             //初始化矩阵tmp 
    65             tmp.mat[0][0] = b;   tmp.mat[0][1] = a;   tmp.mat[0][2] = c;
    66             tmp.mat[1][0] = tmp.mat[2][2] = 1;
    67             tmp.mat[1][1] = tmp.mat[1][2] = tmp.mat[2][0] = tmp.mat[2][1] = 0;
    68             
    69             Matrix p = pow_matrix(tmp, n-2);//相当于求tmp^(n-2)
    70             p = mul(p, arr);
    71             LL ans = (p.mat[0][0] + mod) % mod;
    72             printf("%lld
    ",ans);
    73         }
    74     }
    75     return 0;
    76 }
  • 相关阅读:
    flume,kafka不在一个内网互相打通.md
    尚硅谷Flink2020教程.md
    常用命令.md
    四象限工作效率-事件管理.md
    甘特图目标实施-进度管控.md
    PDCA循环法.md
    SMART大目标拆解小目标.md
    基于内外部竞争环境和竞争条件下的态势分析
    使用Java正则表达式批量提取文本信息
    使用markdown高效编写博客(创建标题)
  • 原文地址:https://www.cnblogs.com/123tang/p/6059906.html
Copyright © 2011-2022 走看看