8.2 stair

来源:互联网 发布:尼坤为什么不火了 知乎 编辑:程序博客网 时间:2024/06/10 07:13

1.【通天阶梯】 stair

【题目描述】

有一个很长很长的通天阶梯,有n级,现在你想要走完这个阶梯。

开始时你在0级,你可以一步走一级或两级。最后一步必须恰好落到第n级上

请你求出有多少种行走方案可以走完这个阶梯。为了降低编程复杂度,只需输出最后的结果mod 123456的值即可

【输入格式】

第一行:

一个整数n

【输出格式】

一行:最后的结果

 

【数据范围】

50%的数据:n<=2^20;

100%的数据:n<=2^64-1;

【样例输入】

2

【样例输出】

2

 

思路:由于数据范围大,所以要用矩阵乘法和幂加速优化

程序:

 type
  arr=array[1..2,1..2]of int64;
var
  f:array[1..2]of longint;
  b:arr;
  n:qword;
procedure ab;
var
  c:array[1..2]of longint;
  i,k,j:longint;
begin
  fillchar(c,sizeof(c),0);
  for k:=1 to 2 do
   for j:=1 to 2 do
    c[j]:=(c[j]+f[k]*b[k,j])mod 123456;
  f:=c;
end;
procedure bb;
var
  c:arr;
  i,j,k:longint;
begin
  fillchar(c,sizeof(c),0);
  for i:=1 to 2 do
   for k:=1 to 2 do
    for j:=1 to 2 do
     c[i,j]:=(c[i,j]+b[i,k]*b[k,j])mod 123456;
  b:=c;
end;
procedure doit;
begin
  readln(n);
  if n=1 then
   begin
     writeln(1);
     exit;
   end;
  if n=2 then
   begin
     writeln(2);
     exit;
   end;
  f[1]:=1;f[2]:=2;
  b[1,1]:=0;b[1,2]:=1;
  b[2,1]:=1;b[2,2]:=1;
  dec(n,2);
  while n>0 do
   begin
     if odd(n) then ab;
     bb;
     n:=n>>1;
   end;
  writeln(f[2]);
end;
begin
  assign(input,'stair.in');
  assign(output,'stair.out');
  reset(input);
  rewrite(output);
  doit;
  close(input);
  close(output);
end.

反思:好好听讲。。。。。