vijos1067守望者的逃离

裸的矩阵乘法,我却调了一上午……弱到爆啊……

不过最终辛苦没有白费,我终于彻底搞懂了

要注意几点:

一、必须构造出前几项

二、用矩阵乘法算法之后还要手工算答案,利用首先算好的前几项

三、想好自己构造的矩阵是横着的还是竖着的

四、要用一个单位矩阵存储最后的结果

代码:(不容易啊)

 1 type matrix=array[1..15,1..15] of int64;
 2 var i,n,k,j:longint;
 3      ans:int64;
 4      a,b:matrix;
 5      f:array[0..15] of int64;
 6 function mo(x:int64):int64;
 7  begin
 8    mo:=x mod 7777777;
 9  end;
10 procedure mul(var x,y,z:matrix);
11  var i,j,l:longint;
12      t:matrix;
13    begin
14      fillchar(t,sizeof(t),0);
15      for i:=1 to k do
16       for j:=1 to k do
17        for l:=1 to k do
18         t[i,j]:=mo(t[i,j]+x[i,l]*y[l,j]);
19      z:=t;
20    end;
21 procedure ksm(times:longint);
22    begin
23    while times<>0 do
24     begin
25       if times and 1=1 then mul(a,b,b);
26       times:=times>>1;
27       mul(a,a,a);
28     end;
29    end;
30 procedure init;
31  begin
32    readln(k);readln(n);
33    fillchar(a,sizeof(a),0);
34    fillchar(b,sizeof(b),0);
35    for i:=1 to k do a[1,i]:=1;
36    for i:=2 to k do a[i,i-1]:=1;
37    for i:=1 to k do b[i,i]:=1;
38    f[0]:=1;f[1]:=1;
39    for i:=2 to k do
40      for j:=0 to i-1 do
41       f[i]:=mo(f[i]+f[j]);
42    if n<=k then begin writeln(f[n]);halt;end;
43  end;
44 procedure main;
45  begin
46    ksm(n-k);
47    ans:=0;
48    for i:=1 to k do ans:=mo(ans+b[1,i]*f[k+1-i]);
49    writeln(ans);
50  end;
51 begin
52   init;
53   main;
54 end.            
View Code
原文地址:https://www.cnblogs.com/zyfzyf/p/3802300.html