Codevs 3332 数列(矩阵乘法)

本文介绍了一个关于3332数列的问题解决方法,利用矩阵乘法和快速幂技术来高效计算数列中特定项的值,并提供了一个完整的C++实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

3332 数列
时间限制: 1 s
空间限制: 256000 KB
题目等级 : 大师 Master
题目描述 Description
a[1]=a[2]=a[3]=1
a[x]=a[x-3]+a[x-1] (x>3)
求a数列的第n项对1000000007(10^9+7)取余的值。
输入描述 Input Description
第一行一个整数T,表示询问个数。
以下T行,每行一个正整数n。
输出描述 Output Description
每行输出一个非负整数表示答案
样例输入 Sample Input
3
6
8
10
样例输出 Sample Output
4
9
19
数据范围及提示 Data Size & Hint
对于30%的数据 n<=100;
对于60%的数据 n<=2*10^7;
对于100%的数据 T<=100,n<=2*10^9;
分类标签 Tags
快速幂 矩阵乘法 数论

/*
矩阵乘法快速幂.
关键在于推矩阵.
这个题矩阵还是比较好推的.
然后很快就A了......
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define mod 1000000007
#define MAXN 4
#define LL long long
using namespace std;
LL b[MAXN][MAXN],a[MAXN][MAXN],ans[MAXN][MAXN],c[MAXN][MAXN];
void mi(int n)
{
    while(n)
    {
        if(n&1)
        {
            for(int i=1;i<=3;i++)
              for(int j=1;j<=3;j++)
                for(int k=1;k<=3;k++)
                  c[i][j]=(c[i][j]+ans[i][k]*b[k][j]%mod)%mod;
            for(int i=1;i<=3;i++)
              for(int j=1;j<=3;j++)
                ans[i][j]=c[i][j],c[i][j]=0;
        }
        for(int i=1;i<=3;i++)
          for(int j=1;j<=3;j++)
            for(int k=1;k<=3;k++)
                c[i][j]=(c[i][j]+b[i][k]*b[k][j]%mod)%mod;
            for(int i=1;i<=3;i++)
              for(int j=1;j<=3;j++)
                b[i][j]=c[i][j],c[i][j]=0;
        n>>=1;
    }
}
void slove(int n)
{
    memset(ans,0,sizeof ans);memset(b,0,sizeof b);
    b[1][1]=ans[1][1]=1,b[1][2]=ans[1][2]=1,
    b[2][3]=ans[2][3]=1,b[3][1]=ans[3][1]=1;
    a[1][1]=a[1][2]=a[1][3]=1;
    mi(n);
    printf("%lld\n",ans[3][1]%mod);
}
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);n--;
        slove(n);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值