[SDOI2008]递归数列

矩阵加速递推。
图片出处见水印

#include <iostream>
#include <cstdio>
#include <cstring>
#define int long long
using namespace std;
int K,b[20],c[20],m,n,p;
long long sum[20];
struct Matrix {
  int g[16][16];
  Matrix(){memset(g,0,sizeof g);}
  Matrix operator * (const Matrix &rhs) const{
    Matrix ans;
    for(int i=0;i<=K;i++)
      for(int j=0;j<=K;j++)
        for(int k=0;k<=K;k++)
          (ans.g[i][k]+=g[i][j]*rhs.g[j][k])%=p;
    return ans;
  }
}A,B;
int ksm(Matrix d,int z) {
  Matrix ans=A;
  while(z) {
    if(z&1) ans=ans*d;
    d=d*d;
    z>>=1;
  }
  return ans.g[0][K];
}
main() {
  scanf("%lld",&K);
  for(int i=0;i<K;i++) scanf("%lld",&b[i]),A.g[0][i]=b[i],A.g[0][K]+=b[i],sum[i]=sum[i-1]+b[i];//cout<<sum[K-1]<<endl<<endl;
  for(int i=0;i<K;i++) scanf("%lld",&c[i]);
  for(int i=0;i<K;i++) B.g[i+1][i]=1;
  for(int i=0;i<K;i++) B.g[i][K-1]=B.g[i][K]=c[K-i-1];
  B.g[K][K-1]=0;B.g[K][K]=1;
  scanf("%lld%lld%lld",&m,&n,&p);
  int C,D;
  m-=K+1,n-=K;
  if(n<=0) C=sum[n+K-1];
  else C=ksm(B,n);
  if(m<=0) D=sum[m+K-1];
  else D=ksm(B,m);
  printf("%lld",(C-D+p)%p);
}
我是咸鱼。转载博客请征得博主同意Orz
原文地址:https://www.cnblogs.com/sdfzhsz/p/9376410.html