矩阵——普通递推数列

矩阵——普通递推数列

概述

最近学习了一下矩阵,终于在疯狂敲了3遍+手写2遍之后能够一节课之内打完了,高兴啊!!!
大概简述一下思路,首先是一个快读,以前看别人打快读那么长以为有多么难,现在仔细一看发现原来没那么难…
之后封装了一个matrix结构体,之后matrix就可以和其他数据结构一样用啦!!!
之后重定义了一下矩阵的乘法运算,还有矩阵的幂次运算,最后读入n:询问的项数,k:递推数列的系数个数,A:递推数列的系数,f0:递推数列的初始值
然后计算就好了…

code

#include<cstdio> 
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
    int f=1,s=0;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')
    {
        s=(s<<1)+(s<<3)+ch-'0';
        ch=getchar();
    }
    return f*s;
}
const int maxn=101,maxm=101,mod=10000;
struct matrix
{
    int n,m;
    long long s[maxn][maxm];
    matrix(){clean();}
    void clean()
    {
        n=maxn,m=maxm;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                s[i][j]=0;
    }
}A,f0;
matrix operator * (matrix a,matrix b)
{
    matrix c;
    if(a.m!=b.n)return c;
    c.n=a.n,c.m=b.m;
    long long ss[maxn];
    for(int j=0;j<c.m;j++)
    {
        for(int i=0;i<b.n;i++)ss[i]=b.s[i][j];
        for(int i=0;i<c.n;i++)
        {
            for(int k=0;k<b.n;k++)
                c.s[i][j]+=a.s[i][k]*ss[k];
            c.s[i][j]%=mod;
        }
    }
    return c;
}
matrix pow(matrix a,int b)
{
    matrix ans;
    ans.n=ans.m=a.n;
    for(int i=0;i<a.n;i++)
        for(int j=0;j<a.m;j++)
            ans.s[i][j]=(i==j);
    for(;b;b>>=1,a=a*a)if(b&1)ans=ans*a;
    return ans;        
}
int n,k;
int main()
{
    n=read();
    k=read();
    for(int i=0;i<k;i++)A.s[0][i]=read();
    for(int i=0;i<k;i++)f0.s[k-i-1][0]=read();
    for(int i=1;i<k;i++)A.s[i][i-1]=1;
    A.n=A.m=k;
    f0.n=k,f0.m=1;
    if(n<k)
    {
        printf("%lld",f0.s[k-n-1][0]);
        return 0;
    }
    matrix tmp=pow(A,1);
    printf("%lld",(pow(A,n-k+1)*f0).s[0][0]);
    return 0;
}