nyoj 301 递推求值 矩阵幂

来源:互联网 发布:windows x键 编辑:程序博客网 时间:2024/05/02 02:46

给你一个递推公式:

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


在涛神的协助下构造出来的矩阵:(貌似发表了就格式乱了,空格用"..."表示)

Fn..........b...a...1......Fn-1

Fn-1..=..1...0...0......Fn-2

c ............0...0...1......c


第一次做矩阵幂的题,自己的理解就是:把二分幂的数与数相乘写成矩阵与矩阵相乘,矩阵幂适用与含有递推关系的递推式。


在乘的过程中需要注意的几点是:

构造出来的系数矩阵需要先进行二分幂的乘法,再去乘初始的矩阵。

        矩阵乘法需要注意是谁乘谁,注意乘的顺序(a*b!=b*a)

        注意取模

        答案的矩阵形式上要和初试矩阵一致

#include <stdio.h>#include <iostream>#include <algorithm>#include <string.h>using namespace std;typedef long long LL;const LL mod = 1000007;struct matrix{    LL a[3][3];}A;matrix mul(matrix t1,matrix t2)   ///矩阵乘法,注意取模{    matrix tmp;    memset(tmp.a,0,sizeof tmp.a);    for(LL i = 0;i < 3;i++)    {        for(LL j = 0;j < 3;j++)        {            for(LL k = 0;k < 3;k++)            {                tmp.a[i][j] += ((t1.a[i][k]%mod)*(t2.a[k][j]%mod))%mod;                tmp.a[i][j] = (tmp.a[i][j]+mod)%mod;            }        }    }    return tmp;}matrix cal(matrix res,LL n){    matrix tmp;    for(LL i = 0;i < 3;i++)  ///构造单位矩阵        for(LL j = 0;j < 3;j++)        if(i == j)            tmp.a[i][j] = 1;        else            tmp.a[i][j] = 0;    while(n)                 ///二分幂    {        if(n&1)            tmp = mul(tmp,A);        n >>= 1;        A = mul(A,A);    }    return tmp;}int main(void){    LL T;    scanf("%lld",&T);    while(T--)    {        LL n;        LL a,b,c;        LL f1,f2;        scanf("%lld%lld%lld%lld%lld%lld",&f1,&f2,&a,&b,&c,&n);        if(n == 1)        {            printf("%lld\n",(f1%mod+mod)%mod);            continue;        }        if(n == 2)        {            printf("%lld\n",(f2%mod+mod)%mod);            continue;        }        memset(A.a,0,sizeof A.a);        A.a[0][0] = b;A.a[0][1] = a;A.a[0][2] = 1;   ///构造系数矩阵        A.a[1][0] = 1;                                    A.a[2][2] = 1;        matrix res;        memset(res.a,0,sizeof res.a);        res.a[0][0] = f2;            ///初试矩阵        res.a[1][0] = f1;        res.a[2][0] = c;        matrix tmp = cal(res,n-2);     ///系数矩阵乘        res = mul(tmp,res);          ///再乘初试矩阵输出(0,0)即Fn        printf("%lld\n",res.a[0][0]);    }    return 0;}


0 0
原创粉丝点击