求递推序列的第N项 【矩阵快速幂】

有一个序列是这样定义的:f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.

给出A,B和N,求f(n)的值。

Input

输入3个数:A,B,N。数字之间用空格分割。(-10000 <= A, B <= 10000, 1 <= N <= 10^9)

Output

输出f(n)的值。

Input示例

3 -1 5

Output示例

6

有的大佬是用找规律找周期写的,我这个菜鸡看的不太懂,用矩阵快速幂写;

上代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<math.h>
#include<map>
#include<vector>
#include<stack>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N=2;
const int mod=7;

ll tmp[N][N];
void multi(ll a[][N],ll b[][N],int n)//矩阵快速幂核心代码
{
    memset(tmp,0,sizeof(tmp));
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
            for(int k=0; k<n; k++)
            {
                tmp[i][j]+=(a[i][k]*b[k][j])%mod;
                tmp[i][j]=(tmp[i][j]+mod)%mod;
            }
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
            a[i][j]=tmp[i][j];
}

ll res[N][N];
void poww(ll a[][N],int m)//求a…^m
{
    memset(res,0,sizeof(res));
    for(int i=0; i<N; i++)
        res[i][i]=1;
    while(m)
    {
        if(m%2)
            multi(res,a,N);
        multi(a,a,N);
        m/=2;
    }
    ll ans[N][N]={1,0,1,0};//f(1)=1,f(2)=1;所以要计算答案
    multi(res,ans,N);
    printf("%lld\n",res[1][0]);
}

int main()
{
    int a,b,n;
    while(~scanf("%d %d %d",&a,&b,&n))
    {
        ll A[N][N]= {a,b,1,0};
        poww(A,n-1);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41984014/article/details/81867197