SSL 2496 线性递推式 矩阵乘法

题意:一个N阶线性递推式是这样的式子:
Fi=A0Fi-n+A1Fi-(n-1)+…+An-1Fi-1+An

也就是说,这个数列的每一项都是由他之前连续N项相加所得。其中还包括一个常数An。 对于一个给定的N阶线性递推式,求出它的第K项是多少。

分析:假设n=3,则对于一个初始矩阵B【f0,f1,f2,a[3]】,我们就构造一个用于递推的矩阵A:

0 0 a0 0

1 0 a1 0

0 1 a2 0

0 0 1 1

容易得知B*A^n=【f[n],f[n+1,f[n+2],a[3]】,那么我们就用矩阵乘法快速幂求出A^n就好啦。

时间复杂度(n^3logk)。

代码:

type
  arr=array[1..100,1..100] of longint;

const
  p=9973;

var
  n,i,ans:longint;
  m:int64;
  a,f:array[1..100] of longint;
  c,d:arr;

procedure cheng(a,b:arr);
var
  i,j,k:longint;
begin
  fillchar(c,sizeof(c),0);
  for i:=1 to n+1 do
    for j:=1 to n+1 do
      for k:=1 to n+1 do
        c[i,j]:=(c[i,j]+a[i,k]*b[k,j]) mod p;
end;

procedure ksm(x:int64);
begin
 if x=1 then exit;
 ksm(x div 2);
 cheng(c,c);
 if x mod 2=1 then cheng(c,d);
end;

begin
  readln(n,m);
  for i:=1 to n+1 do
    read(a[i]);
  for i:=1 to n do
    read(f[i]);
  for i:=1 to n-1 do
  begin
    d[i+1,i]:=1;
    d[i,n]:=a[i];
  end;
  d[n,n]:=a[n]; d[n+1,n]:=1; d[n+1,n+1]:=1;
  c:=d;
  ksm(m);
  for i:=1 to n do
    ans:=(ans+c[i,1]*f[i]) mod p;
  ans:=(ans+a[n+1]*c[n+1,1]) mod p;
  writeln(ans);
end.


你可能感兴趣的:(SSL 2496 线性递推式 矩阵乘法)