procedure2012
It's not worth it to know you're not worth it!

[题目来源]:tyvj1565

[关键字]:递推 矩阵乘法

[题目大意]:守望者一次可以移动1到k步,问她走到第n个格有多少种走法(mod 7777777)。

//=====================================================================================================

[分析]:首先由推出方程,和费波纳契数列很像:f[i]=f[i-1]+f[i-2]+.......+f[i-k]。但是问题是数据范围很大,单纯循环肯定超时,这时要用矩阵加速。

[代码]:

View Code
 1 var
2 n, k: longint;
3 m, m1, m2, m3: array[-1..100,-1..100] of int64;
4
5 procedure cheng(x: longint);
6 var
7 i, j, t: longint;
8 begin
9 if x = 1 then exit;
10 cheng(x div 2);
11 fillchar(m1,sizeof(m1),0);
12 for i := 0 to k-1 do
13 for j := 0 to k-1 do
14 for t := 0 to k-1 do
15 m1[i,j] := (m1[i,j]+m[i,t]*m[t,j]) mod 7777777;
16 m := m1;
17 if odd(x) then
18 begin
19 fillchar(m2,sizeof(m2),0);
20 for i := 0 to k-1 do
21 for j := 0 to k-1 do
22 for t := 0 to k-1 do
23 m2[i,j] := (m2[i,j]+m1[i,t]*m3[t,j]) mod 7777777;
24 m := m2;
25 end;
26 end;
27
28 procedure work;
29 var
30 i, j: longint;
31 begin
32 for i := 0 to k-1 do
33 begin
34 m[0,i] := 1;
35 m[i,i-1] := 1;
36 end;
37 m3 := m;
38 cheng(n-1);
39 {for i := 0 to k-1 do
40 begin
41 for j := 0 to k-1 do
42 write(m[i,j],' ');
43 writeln;
44 end; }
45 fillchar(m1,sizeof(m1),0);
46 fillchar(m2,sizeof(m1),0);
47 m1[0,1] := 1;
48 m1[1,1] := 1;
49 for i := 0 to k-1 do
50 for j := 0 to k-1 do
51 m2[i,1] := (m2[i,1]+m[i,j]*m1[j,1]) mod 7777777;
52 writeln(m2[0,1]);
53 end;
54
55 begin
56 readln(k);
57 readln(n);
58 work;
59 end.



posted on 2011-11-04 23:15  procedure2012  阅读(218)  评论(0编辑  收藏  举报