Basecamp
    Головна
    Задачі
    Змагання
    Курси
    Рейтинг
    Дописи
    Магазин
    Discord
Fibonacci numbers
Увійти
Статті•12 годин тому

Fibonacci numbers

The Fibonacci sequence is one of the most well-known sequences in mathematics and computer science. It is named after the Italian mathematician Leonardo of Pisa, also known as Fibonacci.

https://en.wikipedia.org/wiki/Fibonacci_number

The Fibonacci numbers fn​=f(n) form a sequence where each number after the first two is equal to the sum of the two preceding ones.

They are defined by the following recurrence relation:

f(n)=⎩⎨⎧​0,if n=01,if n=1f(n−1)+f(n−2),if n≥2​

Thus, we have:

f0​=0,f1​=1,fn​=fn−1​+fn−2​

The Fibonacci sequence therefore begins as:

0,1,1,2,3,5,8,13,21,34,55,...

Each term is obtained by adding the two previous terms.

Example. Compute Fibonacci numbers using an array.

The following program fills an integer array fib such that fib[i]=fi​, where fi​ is the i-th Fibonacci number. It then prints the value fib[n] for a given input n.

#include <stdio.h>

int i, n, fib[47];

int main(void)
{
  scanf("%d",&n);

  fib[0] = 0; fib[1] = 1;
  for(i = 2; i <= n; i++)
    fib[i] = fib[i-1] + fib[i-2];

  printf("%d\n",fib[n]);
  return 0;
}
C++
15 lines
202 bytes

The largest Fibonacci number that can be stored in the int data type is:

f46​=1836311903

The largest Fibonacci number that can be stored in the long long data type is:

f92​=7540113804746346429

For computing Fibonacci numbers with index n>92, standard integer types are no longer sufficient due to overflow. In such cases, arbitrary-precision arithmetic must be used, such as the BigInteger type (or equivalent big number libraries in programming languages that do not support built-in large integers).

Example. Compute the n-th Fibonacci number using a recursive function.

The following program implements a direct recursive definition of the Fibonacci sequence. The function fib(n) returns the n-th Fibonacci number according to the recurrence relation.

#include <stdio.h>

int n;

int fib(int n)
{
  if (n == 0) return 0;
  if (n == 1) return 1;
  return fib(n-1) + fib(n - 2);
}

int main(void)
{
  scanf("%d",&n);
  printf("%d\n",fib(n));
  return 0;
}
C++
17 lines
202 bytes

Example. Compute the n-th Fibonacci number using recursion with memoization.

The following program implements a recursive solution enhanced with memoization to avoid redundant computations. Previously computed values are stored in an array, so each Fibonacci number is calculated at most once.

#include <stdio.h>
#include <string.h>
 
int n, fib[46];
 
int f(int n)
{
  // base cases
  if (n == 0) return 0;
  if (n == 1) return 1;

  // if fib[n] has already been computed, return it 
  if (fib[n] != -1) return fib[n]; 

  // otherwise compute and store (memoize) the result
  return fib[n] = f(n-1) + f(n - 2);
}
 
int main(void)
{
  scanf("%d",&n);

  // initialize memoization array:
  // fib[i] = -1 indicates that the value has not been computed yet 
  memset(fib,-1,sizeof(fib));

  printf("%d\n",f(n));
  return 0;
}
C++
29 lines
532 bytes

This approach significantly improves efficiency compared to plain recursion. While the naive recursive solution has exponential complexity, memoization reduces the time complexity to O(n), since each state is evaluated only once.

Java code

import java.util.*;

public class Main
{
  static int fib[] = new int[46];    
  
  static int f(int n)
  {
    if (n == 0) return 0;
    if (n == 1) return 1;
    if (fib[n] != -1) return fib[n];
    return fib[n] = f(n-1) + f(n - 2);
  }
  
  public static void main(String[] args)
  {
    Scanner con = new Scanner(System.in);
    int n = con.nextInt();
    Arrays.fill(fib, -1);
    System.out.println(f(n));     
    con.close();
  }
}
Java
23 lines
441 bytes

Prove the following properties of Fibonacci numbers:

f0​+f1​+f2​+f3​+...+fn​=fn+2​−1

► Base case n=0:f0​=f2​−1. This is true since 0=1−1.

Inductive step. Assume that:

f0​+f1​+f2​+f3​+...+fn−1​=fn+1​−1

Then:

f0​+f1​+f2​+f3​+...+fn​=(f0​+f1​+f2​+f3​+...+fn−1​)+fn​=(fn+1​−1)+fn​=fn+2​−1
f1​+f3​+f5​+...+f2n−1​=f2n​

► Base case n=1:f1​=f2​, which holds since 1=1.

Inductive step. Assume:

f1​+f3​+f5​+...+f2n−1​=f2n​

Then:

f1​+f3​+...+f2n+1​=(f1​+f3​+...+f2n−1​)+f2n+1​=f2n​+f2n+1​=f2n+2​
f2​+f4​+f6​+...+f2n​=f2n+1​−1

► Base case n=1:f2​=f3​−1. This is true since 1=2−1.

Inductive step. Assume:

f2​+f4​+f6​+...+f2n​=f2n+1​−1

Then:

f2​+f4​+...+f2n+2​=(f2​+f4​+...+f2n​)+f2n+2​=(f2n+1​−1)+f2n+2​=f2n+3​−1
f02​+f12​+f22​+...+fn2​=fn​⋅fn+1​

► Base case n=0:f02​=f0​⋅f1​. This is true since 0=0⋅1.

Inductive step. Assume:

f02​+f12​+f22​+...+fn−12​=fn−1​⋅fn​

Then:

f02​+f12​+f22​+...+fn2​=(f02​+f12​+f22​+...+fn−12​)+fn2​=(fn−1​⋅fn​)+fn2​=fn​⋅(fn−1​+fn​)=fn​⋅fn+1​
Eolymp #4730. Fibonacci

Fibonacci numbers is a sequence of numbers f(n), defined by the formula:

  • f(0)=1,

  • f(1)=1,

  • f(n)=f(n−1)+f(n−2)

Given a value of n, find the n-th Fibonacci number.

Input. One nonnegative integer n (n≤45), representing the Fibonacci number to be printed.

Output. Print the n-th Fibonacci number.

Sample input
4
Sample output
5
Open problem
Solution

Compute all Fibonacci numbers and store them in the fib array by assigning fib[i]=f(i). Then print the desired Fibonacci number.

Example

The fib array will be filled as follows:

Algorithm implementation

Compute the Fibonacci numbers and store them in the fib array: fib[i]=f(i).

#define MAX 46
int fib[MAX];

Fill the fib array according to the recursive formula.

fib[0] = 1; fib[1] = 1;
for (int i = 2; i < MAX; i++)
  fib[i] = fib[i-1] + fib[i-2];

Read the input value of n. Print the answer.

scanf("%d",&n);
printf("%d\n",fib[n]);

Algorithm implementation — recursion

Declare the fib array to store Fibonacci numbers: fib[i]=f(i).

#define MAX 46
int fib[MAX];

The recursive function f computes the n-th Fibonacci number. The memoization technique is used.

int f(int n)
{
  if (n <= 1) return 1;
  if (fib[n] != -1) return fib[n];
  return fib[n] = f(n-1) + f(n - 2);
}

The main part of the program. Read the value of n.

scanf("%d",&n);

Assign the value of −1 to all elements of fib array.

memset(fib,-1,sizeof(fib));

Compute and print the value f(n).

printf("%d\n",f(n));

Algorithm implementation — iteration

Read the input number n.

scanf("%d", &n);

Handle the base case.

if (n == 0 || n == 1) 
{
  printf("1\n");
  return 0;
}

Let us assign:

  • the 0-th Fibonacci number to the variable a;

  • the 1-st Fibonacci number to the variable b;

Initially, the variables a and b contain two consecutive Fibonacci numbers.

a = b = 1;
for (i = 2; i <= n; i++) 
{

The variables a and b contain two consecutive Fibonacci numbers.

a=f(i−2),b=f(i−1)

Compute the next Fibonacci number:

c=a+b=f(i−2)+f(i−1)=f(i)
  c = a + b;

Perform a shift, as a result of which a=f(i−1) and b=f(i).

  a = b;
  b = c;
}

Print the answer. The variable b contains the value of f(n).

printf("%lld\n", b);

NO two one's in a row

Find the number of sequences of length n, consisting only of zeros and ones, that do not have two one's in a row.

Let f(n) be the number of sequences consisting of 0 and 1 of length n that do not have two one's in a row.

If the first number in the sequence is 0, then starting from the second place we can build f(n−1) sequences.

If the first number in the sequence is 1, then second number must be 0. In this case, starting from the third position, we can build f(n−2) sequences.

We have Fibonacci numbers with base cases f(1)=2,f(2)=3.

Eolymp #263. Three ones

Compute the number of sequences of length n, consisting only of zeros and ones, where there are no three consecutive ones.

Input. One integer n (1≤n≤105) is given — the length of the sequence.

Output. Print the number of such sequences modulo 12345.

Sample input 1
1
Sample output 1
2
Sample input 2
4
Sample output 2
13
Open problem
Solution

Let f(n) denote the number of valid sequences of length n. consisting of 0s and 1s. Consider constructing such a sequence based on its first element.

If the first element is 0, then the remaining part of the sequence can be any valid sequence of length n−1. Therefore, there are f(n−1) such sequences.

If the first element is 1, consider the possible continuations:

  • If the second element is 0, then the remaining n−2 positions can form any valid sequence of length n−2, giving f(n−2) possibilities;

  • If the second element is 1, then to avoid having three consecutive 1s, the third element must be 0. The remaining n−3 positions can then form any valid sequence of length n−3, giving f(n−3) possibilities.

Thus, we obtain the following recurrence relation:

f(n)=f(n−1)+f(n−2)+f(n−3)

It remains to determine the base cases:

  • f(1)=2, since there are two sequences of length 1: 0 and 1.

  • f(2)=4, since there are four sequences of length 2: 00,01,10 and 11.

  • f(3)=7, since there are seven sequences of length 3: 000,001,010,011,100,101 and 110.

Example

Algorithm implementation

Declare an array f to store the values f(1),f(2),...,f(n).

int f[100010];

Read the input value n.

scanf("%d",&n);

Initialize the base values of the array.

f[1] = 2; f[2] = 4; f[3] = 7;

Compute the values f(i) using the recurrence relation. Perform all calculations modulo 12345.

for(i = 4; i <= n; i++)
  f[i] = (f[i-1] + f[i-2] + f[i-3]) % 12345;

Print the answer.

printf("%d\n",f[n]);

Algorithm implementation – recursion + memorization

Declare an array dp to store intermediate results:

  • dp[i] will store the value f(i)

int dp[100001];

Implement the function f(n), which returns the number of valid sequences of 0s and 1s of length n. Use memoization.

int f(int n)
{
  if (n == 1) return 2;
  if (n == 2) return 4;
  if (n == 3) return 7;
  if (dp[n] != -1) return dp[n];
  return dp[n] = (f(n-1) + f(n-2) + f(n-3)) % 12345;
}
C++
8 lines
175 bytes

The main part of the program. Read the input value n.

scanf("%d",&n);

Initialize the dp array.

memset(dp,-1,sizeof(dp));

Compute and print the value f(n).

printf("%d\n",f(n));
Eolymp #2421. Fibonacci numbers

As is well known, the Fibonacci sequence is defined as follows:

F0​=0,F1​=1,Fn​=Fn−1​+Fn−2​,n>1.

It is named after the Italian mathematician Leonardo Fibonacci, also known as Leonardo of Pisa.

Given two integers n and m, find the greatest common divisor of Fn​ and Fm​.

Input. Each line represents a single test case and contains two integers n and m (1≤n,m≤1018). The number of test cases does not exceed 1000.

Output. For each test case, print on a separate line the value of GCD(Fn​,Fm​) modulo 108.

Sample input
2 3
1 1
100 200
Sample output
1
1
61915075
Open problem
Solution

It is known that Fibonacci numbers satisfy the following identity:

GCD(Fn​,Fm​)=FGCD(n,m)​

This means that the problem reduces to computing the k-th Fibonacci number modulo 108, where

k=GCD(n,m)

Since n,m≤1018, we have k≤1018. Therefore, it is necessary to compute the value of Fk​ mod 108 in O(log2​k) time.

Theorem. To efficiently compute Fibonacci numbers, it is convenient to use matrix exponentiation. It is known that:

(11​10​)k=(Fk+1​Fk​​Fk​Fk−1​​)

Base case. For k=1, we have:

(11​10​)=(F2​F1​​F1​F0​​)

which is true since F0​=0,F1​=1,F2​=1.

Inductive step. Assume that the formula holds for k. Then, for k+1:

(11​10​)k+1=(Fk+1​Fk​​Fk​Fk−1​​)(11​10​)=(Fk+1​+Fk​Fk​+Fk−1​​Fk+1​Fk​​)=(Fk+2​Fk+1​​Fk+1​Fk​​)

Thus, the formula is valid for all k≥1.

It remains to implement raising a matrix to the power k using fast exponentiation in O(log2​k) time.

Example

Fibonacci numbers are defined as follows:

Let's compute the Fibonacci numbers using matrix exponentiation:

(11​10​)2=(11​10​)⋅(11​10​)=(21​11​)=(F3​F2​​F2​F1​​)
(11​10​)4=(21​11​)2=(21​11​)⋅(21​11​)=(53​32​)=(F5​F4​​F4​F3​​)
(11​10​)8=(53​32​)2=(53​32​)⋅(53​32​)=(3421​2113​)=(F9​F8​​F8​F7​​)
Algorithm implementation

Let us declare the constant MOD, modulo which all computations will be performed.

#define MOD 100000000

The function gcd computes the greatest common divisor of two numbers a and b.

long long gcd(long long a, long long b)
{
  return (!b) ? a : gcd(b, a % b);
}

Let us declare a Matrix class and write its constructor.

class Matrix
{
public:
  long long a, b, c, d;
  Matrix(long long a = 1, long long b = 0, 
         long long c = 0, long long d = 1) 
  {
    this->a = a; this->b = b;
    this->c = c; this->d = d;
  }
C++
10 lines
203 bytes

Let us overload the matrix multiplication operator. All computations are performed modulo MOD=108.

  Matrix operator* (const Matrix &x)
  {
    Matrix res;
    res.a = (a * x.a + b * x.c) % MOD;
    res.b = (a * x.b + b * x.d) % MOD;
    res.c = (c * x.a + d * x.c) % MOD;
    res.d = (c * x.b + d * x.d) % MOD;
    return res;
  }
C++
9 lines
233 bytes

Next, overload the operator for raising a matrix to the power n. The time complexity of the algorithm is O(log2​n).

  Matrix operator^ (long long n)
  {
    Matrix x(*this);
    if (n == 0) return Matrix();
    if (n & 1) return x * (x ^ (n - 1));
    return (x * x) ^ (n/2);
  }
};
C++
8 lines
167 bytes

The function fib returns the n-th Fibonacci number Fn​ modulo 108.

long long fib(long long n)
{
  Matrix res(1,1,1,0);
  res = res ^ n;
  return res.b;
}

The main part of the program. Read the input data, compute, and print the value of FGCD(n,m)​.

while(scanf("%lld %lld",&n,&m) == 2)
{
  d = gcd(n,m);
  printf("%lld\n",fib(d));
}

Algorithm implementation – functions

Let us declare the constant MOD, modulo which all computations will be performed.

#define MOD 100000000

The function gcd computes the greatest common divisor of two numbers a and b.

long long gcd(long long a, long long b)
{
  return (!b) ? a : gcd(b, a % b);
}

Declare the Matrix structure — a 2×2 matrix. By default, the identity matrix is created, which is convenient for exponentiation.

struct Matrix 
{
  long long a, b, c, d;
  Matrix(long long a_ = 1, long long b_ = 0,
         long long c_ = 0, long long d_ = 1)
         : a(a_), b(b_), c(c_), d(d_) {}
};
C++
7 lines
175 bytes

The function multiply multiplies two 2×2 matrices using the standard formula.

Matrix multiply(Matrix &x, Matrix &y) 
{
  return Matrix(
    (x.a * y.a + x.b * y.c) % MOD,
    (x.a * y.b + x.b * y.d) % MOD,
    (x.c * y.a + x.d * y.c) % MOD,
    (x.c * y.b + x.d * y.d) % MOD
  );
}
C++
9 lines
204 bytes

The function power implements binary exponentiation of the matrix base to the power exp.

Matrix power(Matrix base, long long exp) 
{
  Matrix result;
  while (exp > 0)
  {
    if (exp & 1)
      result = multiply(result, base);
    base = multiply(base, base);
    exp >>= 1;
  }
  return result;
}
C++
12 lines
210 bytes

The function fib computes the n-th Fibonacci number modulo 108 using the matrix method.

long long fib(long long n) 
{
  if (n == 0) return 0;
  Matrix m(1, 1, 1, 0);
  Matrix res = power(m, n);
  return res.b; // F(n)
}
C++
7 lines
132 bytes

The main part of the program. Read the input data, compute, and print the value of FGCD(n,m)​.

while (scanf("%lld %lld", &n, &m) == 2) 
{
  d = gcd(n, m);
  printf("%lld\n", fib(d));
}

Algorithm implementation – memoization

The following identity is known for Fibonacci numbers:

Fn+m​=Fm​⋅Fn+1​+Fm−1​⋅Fn​

From it, the following special cases directly follow:

  • if m=n, then F2n​=Fn​⋅Fn+1​+Fn−1​⋅Fn​.

  • if m=n+1, then F2n+1​=Fn+1​⋅Fn+1​+Fn​⋅Fn​.

These formulas allow Fibonacci numbers to be computed using a "divide and conquer" approach, reducing the computation of Fn​ to values with indices approximately half as large.

The base cases are handled separately:

F0​=0,F1​=F2​=1

With this approach, the recursion depth is proportional to log2​n, and the time complexity of the algorithm is O(log2​n).

Declare the constant MOD, modulo which all computations will be performed.

#define MOD 100000000

Declare a variable F of type map to store (memoize) the Fibonacci numbers that have already been computed.

map<long long, long long> F;

The function gcd computes the greatest common divisor of two numbers a and b.

long long gcd(long long a, long long b)
{
  return (!b) ? a : gcd(b,a % b);
}

The function fib computes the n-th Fibonacci number modulo 108.

long long fib(long long n)
{

The base cases are handled separately.

  if (n == 0) return 0;
  if (n == 1) return 1;
  if (n == 2) return 1;

If the value of Fn​ has already been computed and stored in F, it is returned immediately without recomputation.

  if (F[n]) return F[n];

Next, we use the decomposition of the number n into:

  • n=2k+1 — odd case: Fn​=Fk2​+Fk+12​.

  • n=2k — even case: Fn​=Fk​⋅Fk+1​+Fk−1​⋅Fk​.

  long long k = n / 2;

Store and return the result.

  if (n % 2 == 1) // n = 2*k + 1
    return F[n] = (fib(k) * fib(k) + fib(k+1) * fib(k+1)) % MOD;
  else // n = 2*k
    return F[n] = (fib(k) * fib(k+1) + fib(k-1) * fib(k)) % MOD;
}

The main part of the program. Read the input data, compute, and print the value of FGCD(n,m)​.

while(scanf("%lld %lld",&a,&b) == 2)
{
  d = gcd(a,b);
  printf("%lld\n",fib(d));
}
Eolymp #1250. Fibonacci problem again

As is well known, the Fibonacci numbers are defined as follows:

F(n)=⎩⎨⎧​0,1,F(n−1)+F(n−2),​n=0,n=1,n>1.​

Given two integers a and b, compute the sum:

S=F(a)+F(a+1)+…+F(b)

Input. Each line represents a separate test case and contains two integers a and b (0≤a≤b≤109).

Output. For each test case, print on a separate line the value of S modulo 109+7.

Sample input
1 1
3 5
10 1000
Sample output
1
10
625271457
Open problem
Solution

Theorem. For the Fibonacci numbers, the following formula holds:

S(n)=F(0)+F(1)+...+F(n)=F(n+2)−1

Proof. We prove the statement by induction.

  • Base case. For n=0 we have:

F(0)=F(2)−1,

That is, 0=1−1, which is true.

  • Inductive step. Assume that:

S(n)=F(n+2)−1

Then:

S(n+1)=F(0)+F(1)+...+F(n)+F(n+1)=(F(n+2)−1)+F(n+1)=F(n+3)−1,

which completes the proof

Then the desired sum

S=F(a)+F(a+1)+...+F(b)

can be computed as

S=S(b)−S(a−1)

Computing Fibonacci numbers using Binet's formula

Consider the generating function for the Fibonacci numbers (F0​=0,F1​=1):

G(x)=n=0∑∞​Fn​xn=F0​+F1​x+n=2∑∞​Fn​xn=F0​+F1​x+n=2∑∞​(Fn−1​+Fn−2​)xn=x+n=2∑∞​Fn−1​xn+n=2∑∞​Fn−2​xn=x+xn=1∑∞​Fn​xn+x2n=0∑∞​Fn​xn=x+xG(x)+x2G(x)

From this it follows that:

G(x)(1−x−x2)=x,G(x)=1−x−x2x​

Let us decompose the generating function into partial fractions. First, find the roots of the denominator:

1−x−x2=(1−φx)(1−ψx),

where

φ=21+5​​,ψ=21−5​​

Now represent the generating function as:

1−x−x2x​=1−φxA​+1−ψxB​

Solving the system, we obtain:

A=5​1​,B=−5​1​

Taking into account that

1−rx1​=n=0∑∞​rnxn,

the generating function can be rewritten as:

G(x)=5​1​(1−φx1​+1−ψx1​)=5​1​n=0∑∞​(φn−ψn)xn

But since

G(x)=n=0∑∞​Fn​xn

equating the coefficients of xn gives:

Fn​=5​φn−ψn​=5​1​((21+5​​)n−(21−5​​)n)=2n5​(1+5​)n−(1−5​)n​

Computing Fibonacci Numbers Using an Identity

For the Fibonacci numbers, the following identity is known:

Fn+m​=Fm​⋅Fn+1​+Fm−1​⋅Fn​

From it, the following special cases follow directly:

  • if m=n, then F2n​=Fn​⋅Fn+1​+Fn−1​⋅Fn​

  • if m=n+1, then F2n+1​=Fn+1​⋅Fn+1​+Fn​⋅Fn​

These formulas make it possible to compute Fibonacci numbers using a divide-and-conquer approach, reducing the computation of Fn​ to values with indices approximately half as large.

The base cases are handled separately:

F0​=0,F1​=F2​=1

With this approach, the recursion depth is proportional to log2​n, and the time complexity of the algorithm is O(log2​n).

Example

Let us compute some Fibonacci numbers using Binet’s formula, working in the extended field Zp​(5​) with a large modulus p.

F2​=5​1​​(21+5​​)2−(21−5​​)2​=225​(1+5​)2−(1−5​)2​=225​(6+25​)−(6−25​)​=45​45​​=1F3​=5​1​​(21+5​​)3−(21−5​​)3​=235​(1+5​)3−(1−5​)3​=235​(16+85​)−(16−85​)​=85​165​​=2F4​=5​1​​(21+5​​)4−(21−5​​)4​=245​(6+25​)2−(6−25​)2​=245​(56+245​)−(56−245​)​=165​485​​=3

Let us illustrate the application of the formulas with an example:

  • if m=n, then F2n​=Fn​⋅Fn+1​+Fn−1​⋅Fn​

  • if m=n+1, then F2n+1​=Fn+1​⋅Fn+1​+Fn​⋅Fn​

F6​=F3​⋅F4​+F2​⋅F3​=2⋅3+1⋅2=6+2=8,F7​=F42​+F32​=32+22=9+4=13
Algorithm implementation

Declare the constant MOD, which will be used as the modulus for all computations.

#define MOD 1000000007

Declare a variable fib of type map to store (memoize) already computed Fibonacci numbers.

map<long long, long long> fib;

The function f computes the n-th Fibonacci number modulo MOD.

long long f(long long n)
{
  if (n == 0) return 0;
  if (n == 1) return 1;
  if (n == 2) return 1;

If the n-th Fibonacci number has already been computed and stored in fib, it is returned immediately without recomputation.

  if (fib[n]) return fib[n];

Next, we decompose the number n as follows:

  • n=2k+1 — odd case: Fn​=Fk2​+Fk+12​.

  • n=2k — even case: Fn​=Fk​⋅Fk+1​+Fk−1​⋅Fk​.

  long long k = n / 2;

Store the result and return it.

  if (n % 2 == 1) // n = 2*k + 1
    return fib[n] = (f(k) * f(k) + f(k + 1) * f(k + 1)) % MOD;
  else // n = 2*k
    return fib[n] = (f(k) * f(k + 1) + f(k - 1) * f(k)) % MOD;
}

The main part of the program. For each test case, read the input data and print the answer.

while (scanf("%lld %lld", &a, &b) == 2)
  printf("%lld\n", (f(b + 2) - f(a + 1) + MOD) % MOD);

Algorithm implementation – Binet's formula

Declare the constant MOD, which will be used as the modulus for all computations.

#define MOD 1000000007

Declare the structure Num to store a number of the form x+y5​.

struct Num
{
  long long x, y; // x + y*sqrt(c)
  Num(long long x_ = 0, long long y_ = 0) : x(x_), y(y_) {}
};

Implement multiplication in the field Zp​(5​). The function mult returns the product of the numbers a and b.

Num mult(Num& a, Num& b)
{
  Num res;
  res.x = (a.x * b.x + 5 * a.y % MOD * b.y) % MOD;
   res.y = (a.x * b.y + a.y * b.x) % MOD;
   return res;
}
C++
7 lines
148 bytes

The function pow performs exponentiation of basen, where base is a number in the field Zp​(5​).

Num pow(Num base, long long n)
{
  Num res = { 1, 0 }; // единица поля
  while (n > 0)
  {
    if (n & 1)
      res = mult(res, base);
    base = mult(base, base);
    n >>= 1;
  }
  return res;
}
C++
12 lines
197 bytes

The function modpow computes the value of ak mod p.

long long pow(long long x, long long n)
{
  long long res = 1;
  x %= MOD;
  while (n > 0)
  {
    if (n & 1) res = res * x % MOD;
    x = x * x % MOD;
    n >>= 1;
  }
  return res;
}
C++
12 lines
185 bytes

The function fib computes the n-th Fibonacci number.

long long fib(long long n)
{

Initialize the constants φ=1+5​ and ψ=1−5​.

  Num phi(1, 1);
  Num psi(1, MOD - 1);

Compute the powers A=φn and B=ψn.

  Num A = pow(phi, n);
  Num B = pow(psi, n);

Since

Fn​=5​1​((21+5​​)n−(21−5​​)n)=2n5​(1+5​)n−(1−5​)n​=2n5​(Ax​+Ay​5​)−(Bx​+By​5​)​,

compute the numerator and denominator separately.

Note that Ax​=Bx​ (so Ax​−Bx​=0), and the coefficient of 5​ in the numerator is Ay​−By​.

  long long numerator = (A.y - B.y + MOD) % MOD;

Compute 2n in the denominator.

  long long denom = pow(2, n);

Both the numerator and the denominator contain a factor of 5​. Cancel this factor, leaving the result to be computed as:

(Ay​−By​)⋅(2n)−1=numerator⋅denom−1
  long long denom_inv = pow(denom, MOD - 2);
  return numerator * denom_inv % MOD;
}

The main part of the program. For each test case, read the input data and print the answer.

while (scanf("%lld %lld", &a, &b) == 2)
  printf("%lld\n", (fib(b + 2) - fib(a + 1) + MOD) % MOD);
Eolymp #8295. Fibonacci strings generation

Generate the n-th Fibonacci string, which is defined by the following recurrence relation:

  • f(0)="a";

  • f(1)="b";

  • f(n)=f(n−1)+f(n−2), where the "+" denotes string concatenation.

For example:

f(3)=f(2)+f(1)=(f(1)+f(0))+f(1)="b"+"a"+"b"="bab"

Input. One integer n (0≤n≤20).

Output. Print the n-th Fibonacci string.

Sample input 1
3
Sample output 1
bab
Sample input 2
5
Sample output 2
babbabab
Open problem
Solution

Implement a recursive function that generates the n-th Fibonacci string.

Algorithm implementation

The function f returns the n-th Fibonacci string.

string f(int n)
{
  if (n == 0) return "a";
  if (n == 1) return "b";
  return f(n-1) + f(n-2);
}

The main part of the program. Read the input value n and print the n-th Fibonacci string.

cin >> n;
cout << f(n) << endl;

Algorithm implementation — without STL

The function f returns the n-th Fibonacci string.

void f(int n)
{
  if (n == 0)
  {
    printf("a"); return;
  }
  if (n == 1)
  {
    printf("b"); return;
  }
  f(n-1);
  f(n-2);
}
C++
13 lines
132 bytes

The main part of the program. Read the input value n and print the n-th Fibonacci string.

scanf("%d",&n);
f(n); printf("\n");
Eolymp #5103. Koza Nostra

While the students are taking an exam, the teachers are playing Mafia. There are n teachers sitting around a round table. The host must deal ace cards to some of them (the number of aces can be arbitrary, including 0) — these teachers will be the mafia. However, no two mafia members are allowed to sit next to each other.

In how many ways can the host deal the cards? Two ways are considered different if there exists at least one teacher who is a mafia member in one case and is not a mafia member in the other.

Input. The number of teachers n (1≤n≤30) sitting around the table.

Output. Print one integer — the number of ways to deal the cards.

Sample input 1
1
Sample output 1
2
Sample input 2
2
Sample output 2
3
Open problem
Solution

Let g(n) be the number of ways to deal cards to n teachers arranged in a line (the first and the last are not considered adjacent). This problem is equivalent to counting binary sequences of length n consisting of 0s and 1s in which no two 1s are adjacent. The solution is given by the Fibonacci sequence defined by the following recurrence relation:

g(n)=⎩⎨⎧​2,n=1,3,n=2,g(n−1)+g(n−2),n≥3.​

Let f(n) be the number of ways to deal cards to n teachers seated in a circle.

  • If the first teacher does not receive an ace, then the remaining n−1 teachers can be dealt aces in g(n−1) ways.

  • If the first teacher does receive an ace, then the second and the last teachers must not receive aces. In this case, the remaining n−3 teachers can be dealt aces in g(n−3) ways.

Thus, we obtain the following relation:

f(n)=g(n−1)+g(n−3), if n≥3

Example

For n=3, we need the value g(0). It can be found from the equality g(0)+g(1)=g(2), which gives

g(0)=g(2)−g(1)=3−2=1

Therefore,

f(3)=g(2)+g(0)=3+1=4

The base cases are as follows:

f(1)=2f(2)=3
Algorithm implementation

Declare an array fib to store the Fibonacci numbers.

#define MAX 46
int fib[MAX];

The main part of the program. Compute the Fibonacci numbers.

fib[0] = 1; fib[1] = 2;
for (int i = 2; i < MAX; i++)
  fib[i] = fib[i - 1] + fib[i - 2];

Read the input number n.

scanf("%d", &n);

Compute the answer res.

if (n == 1) res = 2; else 
if (n == 2) res = 3; else
res = fib[n - 1] + fib[n - 3];

Print the answer.

printf("%d\n", res);
Eolymp #5091. Explosive containers

All containers in the world fall into two categories — with TNT and without.

Only a fool would place a TNT box on top of another TNT box. Since you're clearly not one of them (right?), you know very well that TNT explodes, especially if another TNT box is placed on top of it.

You find yourself in a room filled with a vast number of boxes of both types. Suddenly, a lift emerges from a hatch in the floor. Unfortunately, it is malfunctioning. It has decided to build a tower of n boxes. To assess your chances of survival, you need to calculate the number of possible configurations in which nothing explodes.

By the way, think about it: what is a rational person like you doing in a room full of TNT?

Input. One integer n (1≤n<45).

Output. Print the number of safe ways to build the tower.

Sample input 1
1
Sample output 1
2
Sample input 2
2
Sample output 2
3
Open problem
Solution

Each empty box is represented by 0, and each TNT box by 1. The task is to determine the number of strings of length n, consisting of 0s and 1s, such that no two 1s are adjacent.

The answer to the problem will be the Fibonacci number f(n):

f(n)=⎩⎨⎧​2,n=13,n=2f(n−1)+f(n−2)​

Example

Consider all possible towers of heights n=1,n=2,n=3. Each corresponds to a sequence of 0s and 1s. There are:

  • two towers of height 1: "0","1";

  • three towers of height 2: "00","01","10";

  • five towers of height 3: "000","001","010","100","101";

Algorithm implementation

Declare an array.

#define MAX 45
int fib[MAX];

Fill the elements of the fib array with Fibonacci numbers according to the recurrence formula.

fib[1] = 2; fib[2] = 3;
for (int i = 3; i < MAX; i++)
  fib[i] = fib[i - 1] + fib[i - 2];

Read the input value of n and print the answer.

scanf("%d", &n);
printf("%d\n", fib[n]);

Algorithm implementation – memoization

Declare an array.

#define MAX 45
int fib[MAX];

The function f computes the n-th Fibonacci number.

int f(int n)
{
  if (n == 1) return 2;
  if (n == 2) return 3;
  if (fib[n] != -1) return fib[n];
  return fib[n] = f(n - 1) + f(n - 2);
}
C++
7 lines
139 bytes

The main part of the program. Read the input value of n and print the result.

scanf("%d", &n);
memset(fib, -1, sizeof(fib));
printf("%d\n", f(n));
Eolymp #5092. Honeycomb

A bee, moving inside a honeycomb, can move as shown in the figure:

  • by moves 1 and 2 — from the upper row,

  • by move 3 — from the lower row.

Input. The number of hexagons n (1≤n≤45) in the upper row is given. The lower row contains one hexagon fewer.

Output. Print the number of ways in which the bee can reach the last cell of the upper row starting from the first cell of the same row.

Sample input 1
1
Sample output 1
1
Sample input 2
3
Sample output 2
2
Open problem
Solution

Number all the hexagons consecutively from left to right, top to bottom, as shown in the picture. In this numbering:

  • hexagons in the upper row have odd numbers;

  • hexagons in the lower row have even numbers.

If the upper row contains n hexagons, the rightmost hexagon in the upper row will have number 2n−1.

Let f(k) denote the number of ways to reach the hexagon numbered k from the first hexagon. Since the bee needs to reach hexagon number 2n−1, the answer to the problem will be f(2n−1).

Now, let's consider the transitions between hexagons.

  • Let hexagon k be in the upper row (an odd number). Then the bee can reach it either from hexagon k−2 or from hexagon k−3. Therefore, for odd k the following recurrence holds:

f(k)=f(k−2)+f(k−3)
  • Let hexagon k be in the lower row (an even number). In this case, there is only one possible transition — from the previous hexagon:

f(k)=f(k−1)

To implement the recursion, we need to set the initial values:

f(1)=1,f(2)=1,f(3)=1

These can be easily verified directly from the bee's movement diagram.

Algorithm implementation

Declare an array.

#define MAX 100
int fib[MAX];

Fill the elements of the fib array in accordance with the recurrence relation.

fib[0] = 0; fib[1] = 1; fib[2] = 1;
for (int i = 3; i < MAX; i++)
  if (i % 2 == 1) fib[i] = fib[i-2] + fib[i-3];
  else fib[i] = fib[i-1];

Read the value n and print the answer f(2n−1).

scanf("%d",&n);
printf("%d\n",fib[2*n-1]);

Algorithm implementation – recursion + memorization

Declare an array.

int fib[90];

Implement a recursive function f using memoization.

int f(int n)
{
  if (n == 1) return 1;
  if (n == 2) return 1;
  if (n == 3) return 1;
  if (fib[n] != -1) return fib[n];
  if (n % 2 == 1) return fib[n] = f(n - 1) + f(n - 3);
  return fib[n] = f(n - 1);
}
C++
9 lines
207 bytes

The main part of the program. Read the input value n.

scanf("%d",&n);

Compute and print the answer.

memset(fib,-1,sizeof(fib));
printf("%d\n",f(2*n-1));
Eolymp #7438. Binary password

Jomart uses a binary string as the password for his computer. Recently, he forgot his old password and now wants to obtain a new one, which will be a binary string of length n. He considers a password sufficiently secure if it does not contain two consecutive zeros.

To obtain a new password, Jomart generates a random binary string of length n. If the string is not secure, he generates another one and repeats the process until he obtains a secure password.

Find the expected number of randomly generated passwords Jomart will need before he finds a secure one.

Input. One integer n (1≤n≤60).

Output. Print the expected value as a fraction p/q, where p and q are coprime positive integers.

Sample input 1
1
Sample output 1
1/1
Sample input 2
4
Sample output 2
2/1
Open problem
Solution

A password (a string of length n) is considered secure if it does not contain two consecutive zeros. The number of such strings is equal to the Fibonacci number fn​, defined as follows:

f1​=2 (the strings 0, 1),

f2​=3 (the strings 01, 10, 11),

fn​=fn−1​+fn−2​,n>3

For example, the first Fibonacci numbers are:

The total number of binary strings of length n is 2n. Therefore, the expected number of randomly generated strings required to obtain a secure one is equal to

2n/fn​

This fraction should be reduced by dividing the numerator and the denominator by their greatest common divisor.

Example

For n=1, the answer is 21/f1​=2/2=1/1.

For n=4, the answer is 24/f4​=16/8=2/1.

Algorithm implementation

Declare an array to store the Fibonacci numbers.

long long f[61];

The function gcd computes the greatest common divisor of two numbers.

long long gcd(long long a, long long b)
{
  return (!b) ? a : gcd(b, a % b);
}

The main part of the program. Read the input value n.

scanf("%d", &n);

Compute the Fibonacci numbers.

f[0] = 1; f[1] = 2;
for (i = 2; i <= n; i++)
  f[i] = f[i - 1] + f[i - 2];

The answer is given as a fraction:

num/den=2n/fn​

Reduce this fraction by dividing the numerator and the denominator by their greatest common divisor.

num = (1LL << n);
den = f[n];
d = gcd(num, den);

num /= d;
den /= d;

Print the answer.

printf("%lld/%lld\n", num, den);
Eolymp #9558. Flags

The flag consists of n vertical stripes, each of which can be colored white, red, or blue. Moreover:

  • No two adjacent stripes may have the same color.

  • Any blue stripe must be placed between a red and a white stripe (in any order).

How many ways are there to color a flag with n stripes?

Input. One integer n (1≤n≤106) — the number of stripes on the flag.

Output. Print the number of ways to color a flag with n stripes. The answer should be given modulo 109+7.

Sample input
3
Sample output
4
Open problem
Solution

Let:

  • fr​(n) be the number of ways to color a flag with n stripes, starting with a red stripe;

  • fw​(n) be the number of ways to color a flag with n stripes, starting with a white stripe;

Let’s consider how to compute the function fr​(n):

  • If the stripe following the red one is white, then the remaining flag of length n−1 can be colored in fw​(n−1) ways;

  • If the stripe following the red one is blue, then the stripe after the blue one must be white. After that, the remaining flag of length n−2 can be colored in fw​(n−2) ways;

Thus, we obtain the following equality:

fr​(n)=fw​(n−1)+fw​(n−2)

By analogous reasoning, we obtain:

fw​(n)=fr​(n−1)+fr​(n−2)

The initial conditions for the first recurrence are obvious:

  • fr(1)=1: A flag consisting of one stripe and starting with red can be colored in exactly one way — R.

  • fr(2)=1: If the first stripe is red, then the second stripe cannot be red and cannot be blue (since a blue stripe must be placed between a red and a white stripe). Therefore, the second stripe must be white. The only possible arrangement is RW.

Similarly,

fw​(1)=1,fw​(2)=1

Both functions fr​(n) and fw​(n) define Fibonacci numbers:

fr​(n)=Fn​,fw​(n)=Fn​

The coloring of the flag starts with the first stripe. It can be either red or white. Therefore, the total number of ways to color the flag is

fr​(n)+fw​(n)=2∗Fn​
Algorithm implementation

Declare the constants.

#define MAX 1000001
#define MOD 1000000007

Declare an array fib to store the Fibonacci numbers.

long long fib[MAX];

Read the input value n.

scanf("%d", &n);

Fill the array fib with Fibonacci numbers.

fib[1] = 1; fib[2] = 1;
for (i = 3; i < MAX; i++) 
  fib[i] = (fib[i - 1] + fib[i - 2]) % MOD;

Print the answer.

printf("%lld\n", (2 * fib[n]) % MOD);
Eolymp #4469. Domino

Find the number of ways to completely tile a rectangle of size 2×n with dominoes of size 2×1. Coverings that coincide with themselves under symmetries (rotations or reflections) are considered different.

Input. One integer n (0<n<65536).

Output. Print the number of ways to tile the rectangle with dominoes.

Sample input 1
1
Sample output 1
1
Sample input 2
4
Sample output 2
5
Open problem
Solution

Let f(n) denote the number of ways to tile a 2×n rectangle with 2×1. dominoes. It is clear that

  • f(1)=1, one vertical domino;

  • f(2)=2, either two vertical dominoes or two horizontal dominoes.

Consider the algorithm for computing f(n):

  • we can place one domino vertically, after which the remaining rectangle of length n−1 can be tiled in f(n−1) ways,

  • or we can place two dominoes horizontally, after which the remaining rectangle of length n−2 can be tiled in f(n−2) ways.

Thus, we obtain the recurrence relation:

f(n)=f(n−1)+f(n−2)

Therefore, f(n) is a Fibonacci number.

Algorithm implementation

Since n<65536, long arithmetic or Java programming language should be used.

import java.util.*;
import java.math.*;

public class Main
{
  public static void main(String[] args) 
  {
    Scanner con = new Scanner(System.in);
    int n = con.nextInt();
    
    BigInteger a = new BigInteger("1"), b = a;
    for(int i = 0; i < n; i++)
    {
      BigInteger temp = a.add(b); 
      a = b;
      b = temp;
    }
    
    System.out.println(a);    
    con.close();
  }
}
Java
22 lines
394 bytes

Python implementation

Increase the limit to the required value (for example, 100,000 digits).

import sys
sys.set_int_max_str_digits(100000)

Read the input value n.

n = int(input())

Process the base cases.

if n == 1:
  print(1)
elif n == 2:
  print(2)
else:

Compute the n-th Fibonacci number.

  f1, f2 = 1, 2
  for i in range(n - 2):
    temp = f1 + f2
    f1, f2 = f2, temp

Print the answer.

  print(f2)
Eolymp #2292. Fibonacci number

The Fibonacci numbers are defined as follows:

F(1)=1,F(2)=1,F(n)=F(n−1)+F(n−2),n≥3.

Compute the n-th Fibonacci number.

Input. The first line contains the number of test cases t (1≤t≤103). Each of the next t lines contains one integer n (1≤n≤104).

Output. For each test case, print the corresponding Fibonacci number on a separate line.

Sample input
5
1
2
3
4
5
Sample output
1
1
2
3
5
Open problem
Solution

Since n≤104, computing F(n) requires the use of arbitrary-precision arithmetic or, for example, programming languages such as Java or Python.

Сompute the Fibonacci numbers from 1 to 104 and store them in an array fib. Then, for each input value n print fib[n].

Algorithm implementation
import java.util.*;
import java.math.*;

public class Main
{
  static BigInteger fib[] = new BigInteger[10001];
  
  public static void main(String[] args) 
  {
    Scanner con = new Scanner(System.in);
    fib[2] = fib[1] = BigInteger.ONE;
    for(int i = 3; i < 10001; i++)
      fib[i] = fib[i-1].add(fib[i-2]);
    
    int tests = con.nextInt();
    for(int i = 0; i < tests; i++)
    {
      int n = con.nextInt();
      System.out.println(fib[n]);      
    }
    con.close();
  }
}
Java
23 lines
490 bytes

Java implementation – recursion with memoization

import java.util.*;
import java.math.*;

public class Main
{
  static BigInteger fib[] = new BigInteger[10001];    
  static BigInteger MUNIS1 = new BigInteger("-1");

  static BigInteger f(int n)
  {
    if (n <= 2) return BigInteger.ONE;
    if (fib[n].compareTo(MUNIS1) != 0) return fib[n];
    return fib[n] = f(n-1).add(f(n - 2));
  }
  
  public static void main(String[] args)
  {
    Scanner con = new Scanner(System.in);
    for(int i = 0; i < 10001; i++) fib[i] = MUNIS1;
    int tests = con.nextInt();
    for(int i = 0; i < tests; i++)
    {
      int n = con.nextInt();
      System.out.println(f(n));      
    }
    con.close();
  }
}
Java
28 lines
650 bytes

Python implementation

Initialize the first two Fibonacci numbers: F(1)=1.F(2)=1.

f1, f2 = 1, 1

Create a list fib to store the Fibonacci numbers. The value F(0)=0 is added intentionally so that the indexing matches the problem statement.

fib = [0, f1, f2]

Compute the Fibonacci numbers up to F(10002).

for i in range(10000):
  add = f1 + f2
  fib.append(add)
  f1, f2 = f2, add

Read the number of test cases t.

t = int(input())
for i in range(t):

Read the input value n and print F(n).

  n = int(input())
  print(fib[n])
Eolymp #12317. Field modulo

For the given integers a,b,c,n,p, find the value of the expression:

(a+bc​​)n mod p

Print the result as two numbers x and y such that

x+yc​=(a+bc​​)n mod p

Input. Five integers a,b,c,n,p are given. It is known that:

  • p<109 is a prime number,

  • 0≤a,b<p,

  • 1≤c<p,

  • 0≤n≤1018

Output. Print two integers x and y — the coefficients of 1 and c​ respectively, modulo p.

Note. You should work in the extended field:

Zp​(c​)={x+yc​ ∣ x,y∈Zp​}

Operation rules:

  • Addition

    (x1​+y1​c​)+(x2​+y2​c​)=(x1​+x2​)+(y1​+y2​)c​
  • Multiplication

    (x1​+y1​c​)⋅(x2​+y2​c​)=(x1​x2​+cy1​y2​)+(x1​y2​+x2​y1​)c​

All operations are performed modulo p.

Examples. In the first example:

(2+5​​)2 mod 17=9+45​

In the second example:

(3+25​​)10 mod 17=5+115​
Sample input 1
2 1 5 2 17
Sample output 1
9 4
Sample input 2
3 2 5 10 17
Sample output 2
1 2
Open problem
Solution

All computations should be performed in the extended field:

Zp​(c​)={x+yc​ ∣ x,y∈Zp​}

Operation rules:

  • Addition

(x1​+y1​c​)+(x2​+y2​c​)=(x1​+x2​)+(y1​+y2​)c​
  • Multiplication

(x1​+y1​c​)⋅(x2​+y2​c​)=(x1​x2​+cy1​y2​)+(x1​y2​+x2​y1​)c​

After defining the multiplication operation, elements of the field Zp​(c​) can be raised to a power using the standard binary exponentiation method in O(log2​n) time. This makes it possible to compute (a+bc​)n mod p.

Example

In the first example

(2+5​)2 mod 17=(4+45​+5) mod 17=9+45​

Let us consider the second example:

(3+25​)10 mod 17

Let x=3+25​. We'll compute its powers step by step:

x2=(3+25​)2 mod 17=(9+125​+20) mod 17=12+125​x4=(12+125​)2 mod 17=(144+2885​+720) mod 17=14+165​x8=(14+165​)2 mod 17=(196+4485​+1280) mod 17=14+65​

Now we can compute the result:

x10=x8⋅x2=(14+65​)(12+125​) mod 17=(168+725​+1685​+360) mod 17=1+25​
Algorithm implementation

Let us define a structure Num to store numbers of the form x+yc​.

struct Num
{
  long long x, y; // x + y*sqrt(c)
};

Let's implement multiplication in the field Zp​(c​). The function mult returns the product of two numbers a and b.

Num mult(Num& a, Num& b)
{
  Num res;
  res.x = (a.x * b.x + c * a.y % p * b.y) % p;
  res.y = (a.x * b.y + a.y * b.x) % p;
  return res;
}
C++
7 lines
140 bytes

The function pow implements exponentiation, computing basen, where base is a number in the field Zp​(c​).

Num pow(Num base, long long n)
{
  Num res = { 1, 0 };
  while (n > 0)
  {
    if (n & 1)
      res = mult(res, base);
    base = mult(base, base);
    n >>= 1;
  }
  return res;
}
C++
12 lines
181 bytes

The main part of the program. Read the input data.

scanf("%lld %lld %lld %lld %lld", &a, &b, &c, &n, &p);

Initialize the starting number start=a+bc​.

Num start = { a % p, b % p };

Compute and print the answer ans=startn mod p=(a+bc​)n mod p.

Num ans = pow(start, n);
printf("%lld %lld\n", ans.x, ans.y);
Eolymp #12318. Sum in field

For the given integers a,b,c,n,p, compute the value of the sum:

i=0∑n​(a+bc​​)i mod p

Print the result as two numbers x and y such that

x+yc​=i=0∑n​(a+bc​​)i mod p

Input. Five integers a,b,c,n,p are given. It is known that:

  • p<109 is a prime number,

  • 0≤a,b<p,

  • 1≤c<p,

  • 0≤n≤109

Output. Print two integers x and y — the coefficients of 1 and c​ respectively, modulo p.

Note. You should work in the extended field:

Zp​(c​)={x+yc​ ∣ x,y∈Zp​}

Operation rules:

  • Addition

    (x1​+y1​c​)+(x2​+y2​c​)=(x1​+x2​)+(y1​+y2​)c​
  • Multiplication

    (x1​+y1​c​)⋅(x2​+y2​c​)=(x1​x2​+cy1​y2​)+(x1​y2​+x2​y1​)c​

All operations are performed modulo p.

Examples. In the first example:

i=0∑2​(2+5​​)i mod 17=(1+(2+5​)+(9+45​)) mod 17=12+55​

In the second example:

i=0∑10​(3+25​​)i mod 17=15+65​
Sample input 1
2 1 5 2 17
Sample output 1
9 4
Sample input 2
3 2 5 10 17
Sample output 2
1 2
Open problem
Solution

All computations should be performed in the extended field:

Zp​(c​)={x+yc​ ∣ x,y∈Zp​}

Operation rules:

  • Addition

(x1​+y1​c​)+(x2​+y2​c​)=(x1​+x2​)+(y1​+y2​)c​
  • Multiplication

(x1​+y1​c​)⋅(x2​+y2​c​)=(x1​x2​+cy1​y2​)+(x1​y2​+x2​y1​)c​

Let x=a+bc​. Then the required sum is a finite geometric progression:

1+x+x2+x3+...+xn=x−1xn+1−1​=ba​

It remains to perform the division a=xn+1−1 by b=x−1 in the field Zp​(c​):

ba​=bx​+by​c​ax​+ay​c​​=(bx​+by​c​)(bx​−by​c​)(ax​+ay​c​)(bx​−by​c​)​=bx2​−by2​c(ax​+ay​c​)(bx​−by​c​)​=(ax​+ay​c​)(bx​−by​c​)(bx2​−by2​c)−1

Example

In the first example

i=0∑2​(2+5​)i mod 17=(1+(2+5​)+(9+45​)) mod 17=12+55​

Let's compute this example using the formula:

i=0∑2​(2+5​)i mod 17=(2+5​)−1(2+5​)3−1​==1+5​(8+125​+30+55​)−1​=1+5​37+175​​=1+5​3​=(1+5​)(1−5​)3(1−5​)​=−43(1−5​)​=133−35​​=(3−35​)⋅13−1=(3−35​)⋅4=12−125​=12+55​

In the second example

i=0∑10​(3+25​)i mod 17=15+65​
Algorithm implementation

The function modpow computes the value ak mod p.

long long modpow(long long a, long long k, long long p)
{
  long long res = 1;
  a %= p;
  while (k)
  {
    if (k & 1) res = res * a % p;
    a = a * a % p;
    k >>= 1;
  }
  return res;
}
C++
12 lines
191 bytes

Let's define a structure Num to store numbers of the form x+yc​.

struct Num
{
  long long x, y; // x + y*sqrt(c)
};

Let's implement addition in the field Zp​(c​). The function add returns the sum of two numbers a and b.

Num add(Num& a, Num& b)
{
  Num res;
  res.x = (a.x + b.x) % p;
  res.y = (a.y + b.y) % p;
  return res;
}
C++
7 lines
107 bytes

Let's implement subtraction in the field Zp​(c​). The function sub returns the difference of two numbers a and b.

Num sub(Num& a, Num& b)
{
  Num res;
  res.x = (a.x - b.x + p) % p;
  res.y = (a.y - b.y + p) % p;
  return res;
}
C++
7 lines
115 bytes

Let's implement multiplication in the field Zp​(c​). The function mult returns the product of two numbers a and b.

Num mult(Num& a, Num& b)
{
  Num res;
  res.x = (a.x * b.x + c * a.y % p * b.y) % p;
  res.y = (a.x * b.y + a.y * b.x) % p;
  return res;
}
C++
7 lines
140 bytes

The function pow implements exponentiation of basen, where base is an element of the field Zp​(c​).

Num pow(Num base, long long n)
{
  Num res = { 1, 0 }; // единица поля
  while (n > 0)
  {
    if (n & 1)
      res = mult(res, base);
    base = mult(base, base);
    n >>= 1;
  }
  return res;
}
C++
12 lines
197 bytes

The function divide implements division in the field Zp​(c​). It returns the quotient of the numbers a and b. The division is performed by multiplying by the conjugate:

ba​=bx​+by​c​ax​+ay​c​​=(bx​+by​c​)(bx​−by​c​)(ax​+ay​c​)(bx​−by​c​)​=bx2​−by2​c(ax​+ay​c​)(bx​−by​c​)​=(ax​+ay​c​)(bx​−by​c​)(bx2​−by2​c)−1
Num divide(Num& a, Num& b)
{

Let conj=bx​−by​c​.

  Num conj = { b.x, (p - b.y) % p };

Compute n=(ax​+ay​c​)(bx​−by​c​).

  Num n = mult(a, conj);

Compute denom=bx2​−by2​c.

  long long denom = 
    ((b.x * b.x) % p - ((b.y * b.y) % p * c) % p + p) % p;

Compute the multiplicative inverse and return n/denom=n⋅denom−1.

  long long inv_denom = modpow(denom, p - 2, p); // обратный элемент
  return Num((n.x * inv_denom) % p, (n.y * inv_denom) % p);
}

The main part of the program. Read the input data.

scanf("%lld %lld %lld %lld %lld", &a, &b, &c, &n, &p);

Initialize the number x=a+bc​ and the multiplicative identity of the field one=1+0c​.

Num x = { a % p, b % p };
Num one = { 1, 0 };

Compute num=xn+1−1, denom=x−1.

Num num = pow(x, n + 1);
num = sub(num, one);
Num denom = sub(x, one);

Compute and print the answer res=num/denom=x−1xn+1−1​.

Num res = divide(num, denom);
printf("%lld %lld\n", res.x, res.y);
Eolymp #12483. Fibonacci Fever

Given two integers n and k, compute the value:

i=1∑n​fik​,

where fi​ is the i-th Fibonacci number.

The Fibonacci sequence is defined as follows:

f1​=f2​=1,fn​=fn−1​+fn−2​,n≥3.

Since the answer can be very large, print it modulo 109+7.

Input. One line contains two integers n and k (1≤n≤1018,1≤k≤105) where:

  • n is the number of terms in the sum,

  • k is the exponent applied to each Fibonacci number.

Output. Print one integer — the value of the sum:

i=1∑n​fik​mod(109+7)
Sample input 1
4 1
Sample output 1
7
Sample input 2
5 10
Sample output 2
9825700
Open problem
Solution

Consider the Binet formula:

fi​=5​ϕi−ψi​

where

ϕ=21+5​​,ψ=21−5​​

Then:

fik​=(5​)k(ϕi−ψi)k​=(5​)k1​j=0∑k​(−1)jCkj​ϕi(k−j)ψij=(5​)k1​j=0∑k​(−1)jCkj​(ϕk−jψj)i

Now we sum over i:

i=1∑n​fik​=(5​)k1​j=0∑k​(−1)jCkj​i=1∑n​(ϕk−jψj)i

The inner sum is an ordinary geometric progression:

i=1∑n​xi=x−1x(xn−1)​,where x=ϕk−jψj

To eliminate 5​ and avoid working with floating-point numbers, all computations will be performed in the extended field of the form a+b5​ modulo 109+7.

Example

Consider summing powers with k=3.

fi3​=(5​)3(ϕi−ψi)3​=(5​)3ϕ3i−3ϕ2iψi+3ϕiψ2i−ψ3i​

Then the required sum is:

i=1∑n​fi3​=(5​)3∑i=1n​(ϕ3)i−3∑i=1n​(ϕ2ψ)i+3∑i=1n​(ϕψ2)i−∑i=1n​(ψ3)i​
Algorithm implementation

Declare a constant for the modulus MOD.

#define MOD 1000000007

We'll store the values of binomial coefficients in the array Cnk.

vector<long long> Cnk;

To implement arithmetic in the field ZMOD​[5​], define a structure Num. This structure represents numbers of the form x+y5​.

struct Num
{
  long long x, y;
  Num(long long x = 0, long long y = 0) : x(x% MOD), y(y% MOD) {}
};

The function add implements addition in the field ZMOD​[5​].

Num add(const Num& a, const Num& b)
{
  return Num((a.x + b.x) % MOD, (a.y + b.y) % MOD);
}

The function mult implements multiplication in the field ZMOD​[5​].

Num mult(const Num& a, const Num& b)
{
  return Num(
    (a.x * b.x + 5 * a.y % MOD * b.y) % MOD,
    (a.x * b.y + a.y * b.x) % MOD
  );
}
C++
7 lines
139 bytes

The function pw implements binary exponentiation in the field ZMOD​[5​], where the exponent exp is an integer.

Num pw(Num base, long long exp)
{
  Num res(1, 0);
  while (exp)
  {
    if (exp & 1) res = mult(res, base);
    base = mult(base, base);
    exp >>= 1;
  }
  return res;
}
C++
11 lines
173 bytes

The function pw implements fast binary exponentiation to compute ab modulo MOD.

long long pw(long long a, long long b)
{
  long long res = 1;
  a %= MOD;
  while (b)
  {
    if (b & 1) res = (res * a) % MOD;
    a = a * a % MOD;
    b >>= 1;
  }
  return res;
}
C++
12 lines
182 bytes

The function inv computes the multiplicative inverse of an element a in the field ZMOD​[5​].

If

a=x+y5​,

then its inverse element is given by

a−1=x+y5​1​=x2−5y2x−y5​​
Num inv(const Num& a)
{
  long long den = (a.x * a.x - 5 * a.y * a.y) % MOD;
  if (den < 0) den += MOD;

  long long invDen = pw(den, MOD - 2);

  return Num(
    a.x * invDen % MOD,
    (MOD - a.y) * invDen % MOD
  );
}
C++
12 lines
221 bytes

The function divide implements division in the field ZMOD​[5​]:

ba​=a⋅b−1
Num divide(const Num& a, const Num& b)
{
  return mult(a, inv(b));
}

The main part of the program. Read the input data.

scanf("%lld %lld", &n, &k);

Compute the binomial coefficients Ck0​,Ck1​,Ck2​,...,Ckk​ and store them in the array Cnk. Note that

Cnk[i]=Cki​=Cki−1​⋅ik−i+1​
Cnk.resize(k + 1);
Cnk[0] = 1;
for (i = 1; i <= k; i++)
{
  Cnk[i] = Cnk[i - 1] * (k - i + 1) % MOD;
  Cnk[i] = Cnk[i] * pw(i, MOD - 2) % MOD;
}
C++
7 lines
145 bytes

Compute inv2=2−1modMOD=(MOD+1)/2.

long long inv2 = (MOD + 1) / 2;

Initialize the constants: phi=ϕ=21+5​​ and psi=ψ=21−5​​.

Num phi(inv2, inv2);
Num psi(inv2, MOD - inv2);

Compute ratio=ψ/ϕ.

Num ratio = divide(psi, phi);

Initialize the constants 1 and −1 in the field ZMOD​[5​].

Num one(1, 0);
Num minus_one(MOD - 1, 0);

The answer will be accumulated in the variable res.

Num res(0, 0);

Initialize t=ϕk. Then, in the loop, we will multiply this value by ratio, obtaining

ϕk,ϕk−1ψ,ϕk−2ψ2,...,ϕψk−1,ψk
Num t = pw(phi, k);

In the variable res we compute the sum

i=1∑n​fik​=(5​)k1​j=0∑k​(−1)jCkj​i=1∑n​(ϕk−jψj)i

The required sum contains k+1 terms. Therefore, we perform k+1 iterations.

for (j = 0; j <= k; j++)
{
  Num term;

At this point t=ϕk−jψj. Compute the sum of the geometric progression:

term=i=1∑n​ti=t−1t(tn−1)​

However, the case t=1 should be handled separately, because the formula for the sum of a geometric progression contains division by 0. When t=1 the sum takes the form: 1+1+1+...+1 (n times) and is equal to n.

  if (t.x == 1 && t.y == 0)
    term = Num(n % MOD, 0);
  else
  {
    Num tn = pw(t, n);
    Num num = add(tn, minus_one);     // t^n - 1
    term = mult(t, num);              // t * (t^n - 1)
    Num den = add(t, minus_one);      // t - 1
    term = divide(term, den);         // t * (t^n - 1) / (t – 1)
  }
C++
10 lines
310 bytes

Compute term=(−1)jCkj​⋅term.

  long long coef = Cnk[j];
  if (j & 1) coef = MOD - coef;

  term.x = term.x * coef % MOD;
  term.y = term.y * coef % MOD;

Add the next term term to the result res.

  res = add(res, term);

Multiply t by ratio, obtaining t=ϕk−j−1ψj+1.

  t = mult(t, ratio);
}

It remains to divide res by (5​)k.

Num sqrt5(0, 1);
Num sqrt5k = pw(sqrt5, k);
res = divide(res, sqrt5k);

Print the answer.

printf("%lld\n", res.x);

List of problems

  • 4730. Fibonacci

  • 263. Three ones

  • 2421. Fibonacci numbers

  • 1250. Fibonacci problem again

  • 8295. Fibonacci string generation

  • 5103. Koza Nostra

  • 5091. Explosive containers

  • 5092. Honeycomb

  • 7438. Binary password

  • 9558. Flags

  • 4469. Domino

  • 2292. Fibonacci number

  • 12317. Field modulo

  • 12318. Sum in Field

  • 12483. Fibonacci fever


2

Коментарі

Завантаження

Секундочку, отримую дані з серверу

Покищо нічого

Будьте першим, хто розпочне обговорення!
Увійти