动态规划的实现形式之一是递推,因此递推在OI中十分重要。在某信息学的分支学科中,LC学会了如何求一阶线性递推数列。由于他想在正在学习主干学科,因此希望知道求出N阶线性递推数列。为此,他了解到了以下的内容:
一个N阶线性递推式是这样的式子:
也就是说,这个数列的每一项都是由他之前连续N项相加所得。其中还包括一个常数An。
例如,当N=2,A0=A1=1,A2=0时,这个式子就是我们熟悉的斐波那契数列。当然,作为边界条件,F0、F1……Fn-1都是已知的。
LC对这如何去求这个式子一筹莫展,因此请你来帮助他。你的任务就是对于一个给定的N阶线性递推式,求出它的第K项是多少。
第一行两个整数:N,K,其中N表示这个式子是N阶线性递推式,K表示你需要求得那一项。
第二行有N+1个整数:A0,A1,…,An,表示这个递推式的系数。
第三行有N个整数:F0,F1,….,Fn-1,表示数列的初始值。
只有一行,其中只有一个整数,表示这个数列第K项的值。由于数据较大,你只需输出结果 mod 9973的值。
2 10
1 1 0
0 1
55
对于50%的数据:N<=K<=10^6
对于100%的数据:1〈N〈=10
N<=K<=10^18
1<=Ai,Fi<=10^4
这题调起来要死人。。。
[FkFk−1...Fk−n+101]=[Fn−1Fn−2...F001]⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢A0A1A2...An−10An100...000010...000001...001.....................000...100000...001⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
inline const long long Get_Int() {
long long num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}
typedef long long LL;
const int maxn=15,mod=9973;
struct Matrix {
LL n,m,a[maxn][maxn];
Matrix(LL n,LL m) {
this->n=n;
this->m=m;
memset(a,0,sizeof(a));
}
Matrix(LL n,LL m,char E) { //单位矩阵
this->n=n;
this->m=m;
memset(a,0,sizeof(a));
for(int i=1; i<=n; i++)a[i][i]=1;
}
void init(LL n,LL m) {
this->n=n;
this->m=m;
memset(a,0,sizeof(a));
}
LL* operator [] (const LL x) {
return a[x];
}
Matrix operator = (Matrix b) {
init(b.n,b.m);
for(int i=1; i<=b.n; i++)
for(int j=1; j<=b.m; j++)
a[i][j]=b[i][j];
}
Matrix operator + (Matrix& b) {
for(int i=1; i<=b.n; i++)
for(int j=1; j<=b.m; j++)
a[i][j]+=b[i][j];
}
void operator += (Matrix& b) {
*this=*this+b;
}
Matrix operator - (Matrix& b) {
for(int i=1; i<=b.n; i++)
for(int j=1; j<=b.m; j++)
a[i][j]-=b[i][j];
}
void operator -= (Matrix& b) {
*this=*this-b;
}
Matrix operator * (LL k) {
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
a[i][j]*=k;
}
void operator *= (LL k) {
*this=*this*k;
}
Matrix operator * (Matrix& b) {
Matrix c(n,b.m);
for(int i=1; i<=n; i++)
for(int j=1; j<=b.m; j++)
for(int k=1; k<=m; k++)
c[i][j]=(c[i][j]+a[i][k]*b[k][j])%mod;
return c;
}
void operator *= (Matrix& b) {
*this=*this*b;
}
Matrix operator ^ (LL b) {
Matrix ans(n,m,'e'),a=*this;
while(b>0) {
if(b&1)ans=ans*a;
a*=a;
b>>=1;
}
return ans;
}
void Output() {
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++)
printf("%lld ",a[i][j]);
putchar('\n');
}
}
};
LL n,k;
int main() {
n=Get_Int();
k=Get_Int();
Matrix a(1,n+2),b(n+5,n+2); //初始矩阵及系数矩阵
for(int i=n; i>=1; i--)b[i][1]=Get_Int();
a[1][n+2]=1;
b[n+2][1]=Get_Int();
for(int i=1; i<=n; i++)b[i][i+1]=1;
b[n+2][n+2]=1;
for(int i=n; i>=1; i--)a[1][i]=Get_Int();
Matrix tmp=b^(k-n+1);
printf("%lld\n",(a*tmp)[1][1]);
return 0;
}