数列(矩阵乘法+快速幂)

数列

题目描述:
a[1]=a[2]=a[3]=1
a[x]=a[x-3]+a[x-1] (x>3)
求a数列的第n项对1000000007(10^9+7)取余的值。
输入描述:
第一行一个整数T,表示询问个数。
以下T行,每行一个正整数n。
输出描述:
每行输出一个非负整数表示答案
样例输入:
3
6
8
10
样例输出:
4
9
19
数据范围及提示:
对于30%的数据 n<=100;
对于60%的数据 n<=2*10^7;
对于100%的数据 T<=100,n<=2*10^9;
初始矩阵:
1 0 1
1 0 0
0 1 0
初始矩阵的n-4次方,对第一行求和,即为答案

#include<iostream>
#include<cstdio>
#include<cstring>
#define lon long long
using namespace std;
const int mod=1000000007;
lon t,n,ans,a[4][4],b[4][4];
void mul(lon p[4][4],lon q[4][4])
{
    lon tmp[4][4]={0};
    for(int i=1;i<=3;i++)
      for(int j=1;j<=3;j++)
        for(int k=1;k<=3;k++)
        tmp[i][j]=(tmp[i][j]+p[i][k]*q[k][j]%mod)%mod;
    for(int i=1;i<=3;i++)
      for(int j=1;j<=3;j++)
      p[i][j]=tmp[i][j];
}
void quick_power(int x,int p)
{
    while(x)
    {
        if(x&1)
        mul(b,a);
        mul(a,a);
        x>>=1;
    }
}
int main()
{
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld",&n);ans=0;
        if(n==1||n==2||n==3)
        {printf("1
");continue;}
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        a[1][1]=a[1][3]=a[2][1]=a[3][2]=1;
        b[1][1]=b[1][3]=b[2][1]=b[3][2]=1;
        quick_power(n-4,mod);
        for(int i=1;i<=3;i++)
        ans+=b[1][i]%mod;
        cout<<ans%mod;printf("
"); 
    }
    return 0;
}
原文地址:https://www.cnblogs.com/cax1165/p/6070868.html