递推求值

递推求值

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 4
描述

给你一个递推公式:

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


解题报告:这道题是矩阵快速幂模板题。

矩阵A:                    矩阵B:

b a c                         f2 0 0

1 0 0                         f1 0 0

0 0 1                          1 0 0

当n>=3时,Fn=A^(n-2)*B;


code :

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<sstream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
const int mod=1000007;/*求余*/
struct Matrix
{
    int m[3][3]; /*下标从0开始*/
};

Matrix Mul(Matrix a,Matrix b)/*矩阵乘法*/
{
    Matrix c;
    memset(c.m,0,sizeof(c.m));
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            for(int k=0;k<3;k++)
                c.m[i][j]= (c.m[i][j]+a.m[i][k]*b.m[k][j] + mod)%mod;
    return c;
}

Matrix fastm(Matrix a,int n) /*矩阵a的n次方*/
{
    Matrix res;/*初始化为单位矩阵*/
    memset(res.m,0,sizeof(res.m));
    res.m[0][0] = res.m[1][1]= res.m[2][2]=1;
    while(n)
    {
        if(n&1) res = Mul(res,a);
        n>>=1;
        a = Mul(a,a);
    }
    return res;
}

int main()
{
  //  freopen("input.txt","r",stdin);
    int t,n,f1,f2,a,b,c;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d%d%d%d",&f1,&f2,&a,&b,&c,&n);
        if(n==1) printf("%d\n",f1);
        else if(n==2) printf("%d\n",f2);
        else{
            Matrix t,k;
            k.m[0][0]=f2;k.m[0][1]=0;k.m[0][2]=0;
            k.m[1][0]=f1;k.m[1][1]=0;k.m[1][2]=0;
            k.m[2][0]=1;k.m[2][1]=0;k.m[2][2]=0;

            t.m[0][0]=b;t.m[0][1]=a;t.m[0][2]=c;
            t.m[1][0]=1;t.m[1][1]=0;t.m[1][2]=0;
            t.m[2][0]=0;t.m[2][1]=0;t.m[2][2]=1;
            t=fastm(t,n-2);
            printf("%d\n",Mul(t,k).m[0][0]);
        }
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值