SSL_1532
题目描述
Fi=a0*Fi-n+a1*Fi-(n-1)+...+an-1*Fi-1+an
输入n,a0..an,f0,f1的值
求第m项 mod 9973 的值
Sample Input
2 10
1 1 0
0 1
Sample Output
55
数据范围
1<=n<=10
n<=m<=10^18
1<=ai,fi<=10^4
求解思路
因为数据规模较大,所以简单的递推不能解决,使用矩阵乘法。
|f1 f2 ... fn 1| 初始矩阵
|f2 f3 ... fn+1 1| 第2个
(fn+1=a0*f1+a1*f2+...+an-1*fn-1+an)
所以构造矩阵(n+1*n+1)
0 a1 0
A an 1
A是一个对角线为1的n-1*n-1的矩阵
第n列依次为a1,a2...an
n+1行n+1列为1
其余为0
构造代码
l:=n+1;
for i:=1 to n+1 do
read(q[i,n]);
for i:=1 to n-1 do
q[i+1,i]:=1;
q[l,l]:=1;
for i:=1 to n do
read(a[1,i]);
a[1,l]:=1;
利用快速幂求出q的n-m+1次方
乘初始矩阵a
代码
const
p=9973;
type
arr=array[1..100,1..100] of longint;
var
a,s,q:arr;
i,j,k,n,l:longint;
m:int64;
function cheng(x,y:arr;a,b,c:longint):arr;
var
i,j,k:longint;
begin
fillchar(cheng,sizeof(cheng),0);
for i:=1 to a do
for j:=1 to c do
for k:=1 to b do
cheng[i,j]:=(cheng[i,j]+(x[i,k]*y[k,j]) mod p) mod p;
end;//矩阵相乘
function dfs(x:int64):arr;
var
t:arr;
begin
if x=1 then exit(q);
t:=dfs(x div 2);
dfs:=cheng(t,t,l,l,l);
if x mod 2=1 then
dfs:=cheng(dfs,q,l,l,l);
end;//快速幂
procedure init;
begin
readln(n,m);
l:=n+1;
for i:=1 to n+1 do
read(q[i,n]);
for i:=1 to n-1 do
q[i+1,i]:=1;
q[l,l]:=1;
for i:=1 to n do
read(a[1,i]);
a[1,l]:=1;
for i:=1 to l do
for j:=1 to l do
q[i,j]:=q[i,j] mod p;
end;
procedure main;
begin
s:=dfs(m-n+1);
s:=cheng(a,s,1,l,l);
writeln(s[1,n] mod p);
end;
begin
init;
main;
end.
时间复杂度 (n^3 log m)
注意的地方
数据规模有10^18,所以要用Int64