Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const
- size: longint = 8;
- md: int64 = 1000 * 1000 * 1000 + 7;
- type
- vector = record
- vect: array[1..20] of int64;
- end;
- matrix = record
- matr: array[1..20, 1..20] of int64;
- end;
- var
- l, r, ans: int64;
- a: matrix;
- x: vector;
- function create_vector: vector;
- var i: longint; v: vector;
- begin
- for i := 1 to size do
- v.vect[i] := 0;
- create_vector := v;
- end;
- function create_matrix: matrix;
- var i, j: longint; z: matrix;
- begin
- for i := 1 to size do
- for j := 1 to size do
- z.matr[i, j] := 0;
- create_matrix := z;
- end;
- function create_eye_matrix: matrix;
- var i, j: longint; e: matrix;
- begin
- for i := 1 to size do
- for j := 1 to size do
- if i = j then
- e.matr[i, j] := 1
- else
- e.matr[i, j] := 0;
- create_eye_matrix := e;
- end;
- function matrix_matrix_product(a, b: matrix): matrix;
- var i, j, k: longint; c: matrix;
- begin
- c := create_matrix;
- for i := 1 to size do
- for j := 1 to size do
- for k := 1 to size do
- c.matr[i, j] := (c.matr[i, j] + a.matr[i, k] * b.matr[k, j]) mod md;
- matrix_matrix_product := c;
- end;
- function matrix_sum(a, b: matrix): matrix;
- var i, j: longint; c: matrix;
- begin
- c := create_matrix;
- for i := 1 to size do
- for j := 1 to size do
- c.matr[i, j] := (a.matr[i, j] + b.matr[i, j]) mod md;
- matrix_sum := c;
- end;
- function matrix_vector_product(a: matrix; x: vector): vector;
- var i, j: longint; b: vector;
- begin
- b := create_vector;
- for i := 1 to size do
- for j := 1 to size do
- b.vect[i] := (b.vect[i] + a.matr[i, j] * x.vect[j]) mod md;
- matrix_vector_product := b;
- end;
- function matrix_pow(a: matrix; p: int64): matrix;
- var b: matrix;
- begin
- if p = 0 then begin
- matrix_pow := create_eye_matrix;
- exit;
- end;
- if p mod 2 = 0 then begin
- b := matrix_pow(a, p div 2);
- matrix_pow := matrix_matrix_product(b, b);
- end else
- matrix_pow := matrix_matrix_product(a, matrix_pow(a, p - 1));
- end;
- function sum_of_vector_components(v: vector): int64;
- var i: longint; s: int64;
- begin
- s := 0;
- for i := 1 to size do s := (s + v.vect[i]) mod md;
- sum_of_vector_components := s;
- end;
- function pow(a, p: int64): int64;
- var b: int64;
- begin
- if p = 0 then begin
- pow := 1;
- exit;
- end;
- if p mod 2 = 0 then begin
- b := pow(a, p div 2);
- pow := (b * b) mod md;
- end else
- pow := (a * pow(a, p - 1)) mod md;
- end;
- function inverse(a: int64): int64;
- begin
- inverse := pow(a, md - 2);
- end;
- function get_matrix_product(n: int64): matrix; // (E + A) * (E + A^2) * ... * (E + A^b)
- var i: longint; m: matrix;
- begin
- m := create_eye_matrix;
- i := 1;
- while i <= n do begin
- m := matrix_matrix_product(m, matrix_sum(create_eye_matrix, matrix_pow(a, i)));
- i := i * 2;
- end;
- get_matrix_product := m;
- end;
- function get_matrix_sum(n: int64): matrix; // E + A + A^2 + ... + A^n
- var a1, a2, m1, m2: matrix; b: int64;
- begin
- if n = 0 then begin
- get_matrix_sum := create_eye_matrix;
- exit;
- end;
- if n = 1 then begin
- get_matrix_sum := matrix_sum(create_eye_matrix, a);
- exit;
- end;
- b := 1;
- while 2 * b - 1 <= n do b := b * 2;
- b := b div 2;
- a1 := get_matrix_product(b);
- a2 := create_matrix;
- if n > 2 * b - 1 then begin
- m1 := matrix_pow(a, 2 * b);
- m2 := get_matrix_sum(n - 2 * b);
- a2 := matrix_matrix_product(m1, m2);
- end;
- get_matrix_sum := matrix_sum(a1, a2);
- end;
- function get_full(l, r: int64): int64;
- var m, m1, m2: matrix; v: vector;
- begin
- m1 := matrix_pow(a, l - 2);
- m2 := get_matrix_sum(r - l);
- m := matrix_matrix_product(m1, m2);
- v := matrix_vector_product(m, x);
- get_full := (sum_of_vector_components(v) * inverse(2)) mod md;
- end;
- function get_palind(l, r: int64): int64;
- begin
- if l mod 2 = 0 then inc(l);
- if r mod 2 = 0 then dec(r);
- if l > r then
- get_palind := 0
- else begin
- l := (l + 1) div 2;
- r := (r + 1) div 2;
- get_palind := get_full(l, r);
- end;
- end;
- function get_answer(l, r: int64): int64;
- var a, b: int64;
- begin
- a := get_full(l, r);
- b := get_palind(l, r);
- get_answer := (a + b) mod md;
- end;
- procedure init_dp;
- var i: longint;
- begin
- x := create_vector;
- for i := 1 to size do x.vect[i] := 1;
- a := create_matrix;
- a.matr[1, 3] := 1; a.matr[1, 7] := 1;
- a.matr[2, 3] := 1; a.matr[2, 7] := 1;
- a.matr[3, 1] := 1;
- a.matr[4, 5] := 1;
- a.matr[5, 4] := 1; a.matr[5, 8] := 1;
- a.matr[6, 4] := 1; a.matr[6, 8] := 1;
- a.matr[7, 2] := 1; a.matr[7, 6] := 1;
- a.matr[8, 2] := 1; a.matr[8, 6] := 1;
- end;
- begin
- read(l, r);
- ans := 0;
- if (l = 1) and (r = 1) then begin
- writeln(4);
- halt;
- end;
- if (l = 1) then begin
- ans := 4;
- l := 2;
- end;
- init_dp;
- ans := (ans + get_answer(l, r)) mod md;
- writeln(ans);
- end.
Advertisement
Add Comment
Please, Sign In to add comment