Nyoj 301 递推求值

来源:互联网 发布:mac air 11.6装双系统 编辑:程序博客网 时间:2024/04/19 16:20

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=301

问题意思:

给你一个递推公式:

f(x)=a*f(x-2)+b*f(x-1)+c。给你a,b,c,f1,f2,求第n项。

其中0<=f(1),f(2)<100,-100<=a,b,c<=100,1<=n<=1000000000 (10^9)

这就用到了刚学的矩阵快速幂求递推值。

思路:

[fn, fn-1, 1] = [fn-1,fn-2, 1] * A,A为一个3*3的矩阵。可以求解出来。

A = {

   b,1,0,

   a,0,0,

   c,0,1,

};

这 样就很简单了。[fn, fn-1,1] = [f1,f2,1]*A^n-2;求出来的1*3的矩阵就是一个答案。。

Code:

#include <iostream>#include <cstring>#include <cmath>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define LL long longconst LL mod = 1e6 + 7;const int N = 5;struct Matrix{    int n, m;    LL a[N][N];    Matrix(){        memset(a, 0, sizeof(a));    }}A, B;Matrix operator * (Matrix a, Matrix b){    Matrix ans;    ans.n = a.n; ans.m = b.m;    for(int i = 1; i <= a.n; i ++){        for(int j = 1; j <= b.m; j ++){            for(int k = 1; k <= b.n; k ++)            ans.a[i][j] = ((ans.a[i][j] + a.a[i][k] * b.a[k][j]) % mod + mod) % mod;        }    }    return ans;}LL Quick_Power(LL n){    Matrix ans = A, k = B;    while(n){        if(n & 1) {            ans = ans * k;        }        k = k * k;        n = n >> 1;    }    return (ans.a[1][1] % mod + mod) % mod;}int main(){    int T;    LL f1, f2, a, b, c, n;    cin >> T;    while(T -- && cin >> f1 >> f2 >> a >> b >> c >> n){        A.n = 1; A.m = 3;        A.a[1][1] = f2; A.a[1][2] = f1; A.a[1][3] = 1;        B.n = 3; B.m = 3;        B.a[1][1] = b; B.a[2][1] = a; B.a[3][1] = c;        B.a[1][2] = 1; B.a[3][3] = 1;        if(n == 1){            cout << (f1 % mod + mod) % mod<< endl;            continue;        }        if(n == 2){            cout << (f2 % mod + mod) % mod<< endl;            continue;        }        cout<< Quick_Power(n - 2) << endl;    }    return 0;}

学习了一个矩阵快速幂求解递推值的好办法。。!!

0 0