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.
The Fibonacci numbers 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:
Thus, we have:
The Fibonacci sequence therefore begins as:
Each term is obtained by adding the two previous terms.
Example. Compute Fibonacci numbers using an array.
The following program fills an integer array such that , where is the -th Fibonacci number. It then prints the value for a given input .
#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;
}The largest Fibonacci number that can be stored in the int data type is:
The largest Fibonacci number that can be stored in the long long data type is:
For computing Fibonacci numbers with index , 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 -th Fibonacci number using a recursive function.
The following program implements a direct recursive definition of the Fibonacci sequence. The function returns the -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;
}Example. Compute the -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;
}This approach significantly improves efficiency compared to plain recursion. While the naive recursive solution has exponential complexity, memoization reduces the time complexity to , 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();
}
}Prove the following properties of Fibonacci numbers:
► Base case . This is true since .
Inductive step. Assume that:
Then:
► Base case , which holds since .
Inductive step. Assume:
Then:
► Base case . This is true since .
Inductive step. Assume:
Then:
► Base case . This is true since .
Inductive step. Assume:
Then:
Compute all Fibonacci numbers and store them in the array by assigning . Then print the desired Fibonacci number.
Example
The array will be filled as follows:
Compute the Fibonacci numbers and store them in the array: .
#define MAX 46 int fib[MAX];
Fill the 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 . Print the answer.
scanf("%d",&n);
printf("%d\n",fib[n]);Algorithm implementation — recursion
Declare the array to store Fibonacci numbers: .
#define MAX 46 int fib[MAX];
The recursive function f computes the -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 .
scanf("%d",&n);Assign the value of to all elements of array.
memset(fib,-1,sizeof(fib));
Compute and print the value .
printf("%d\n",f(n));Algorithm implementation — iteration
Read the input number .
scanf("%d", &n);Handle the base case.
if (n == 0 || n == 1)
{
printf("1\n");
return 0;
}Let us assign:
the -th Fibonacci number to the variable ;
the -st Fibonacci number to the variable ;
Initially, the variables and contain two consecutive Fibonacci numbers.
a = b = 1;
for (i = 2; i <= n; i++)
{The variables and contain two consecutive Fibonacci numbers.
Compute the next Fibonacci number:
c = a + b;
Perform a shift, as a result of which and .
a = b; b = c; }
Print the answer. The variable contains the value of .
printf("%lld\n", b);NO two one's in a row
Find the number of sequences of length , consisting only of zeros and ones, that do not have two one's in a row.
Let be the number of sequences consisting of and of length that do not have two one's in a row.
If the first number in the sequence is , then starting from the second place we can build sequences.
If the first number in the sequence is , then second number must be . In this case, starting from the third position, we can build sequences.
We have Fibonacci numbers with base cases .
Compute the number of sequences of length , consisting only of zeros and ones, where there are no three consecutive ones.
Input. One integer is given — the length of the sequence.
Output. Print the number of such sequences modulo .
1
2
4
13
Let denote the number of valid sequences of length . consisting of s and s. Consider constructing such a sequence based on its first element.
If the first element is , then the remaining part of the sequence can be any valid sequence of length . Therefore, there are such sequences.
If the first element is , consider the possible continuations:
If the second element is , then the remaining positions can form any valid sequence of length , giving possibilities;
If the second element is , then to avoid having three consecutive s, the third element must be . The remaining positions can then form any valid sequence of length , giving possibilities.
Thus, we obtain the following recurrence relation:
It remains to determine the base cases:
, since there are two sequences of length : and .
, since there are four sequences of length : and .
, since there are seven sequences of length : and .
Example
Declare an array to store the values .
int f[100010];
Read the input value .
scanf("%d",&n);Initialize the base values of the array.
f[1] = 2; f[2] = 4; f[3] = 7;
Compute the values using the recurrence relation. Perform all calculations modulo .
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 to store intermediate results:
will store the value
int dp[100001];
Implement the function , which returns the number of valid sequences of s and s of length . 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;
}The main part of the program. Read the input value .
scanf("%d",&n);Initialize the array.
memset(dp,-1,sizeof(dp));
Compute and print the value .
printf("%d\n",f(n));As is well known, the Fibonacci sequence is defined as follows:
It is named after the Italian mathematician Leonardo Fibonacci, also known as Leonardo of Pisa.
Given two integers and , find the greatest common divisor of and .
Input. Each line represents a single test case and contains two integers and . The number of test cases does not exceed .
Output. For each test case, print on a separate line the value of modulo .
2 3 1 1 100 200
1 1 61915075
It is known that Fibonacci numbers satisfy the following identity:
This means that the problem reduces to computing the -th Fibonacci number modulo , where
Since , we have . Therefore, it is necessary to compute the value of in time.
Theorem. To efficiently compute Fibonacci numbers, it is convenient to use matrix exponentiation. It is known that:
Base case. For , we have:
which is true since .
Inductive step. Assume that the formula holds for . Then, for :
Thus, the formula is valid for all .
It remains to implement raising a matrix to the power using fast exponentiation in time.
Example
Fibonacci numbers are defined as follows:
Let's compute the Fibonacci numbers using matrix exponentiation:
Let us declare the constant , modulo which all computations will be performed.
#define MOD 100000000
The function gcd computes the greatest common divisor of two numbers and .
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;
}Let us overload the matrix multiplication operator. All computations are performed modulo .
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;
}Next, overload the operator for raising a matrix to the power . The time complexity of the algorithm is .
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);
}
};The function fib returns the -th Fibonacci number modulo .
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 .
while(scanf("%lld %lld",&n,&m) == 2)
{
d = gcd(n,m);
printf("%lld\n",fib(d));
}Algorithm implementation – functions
Let us declare the constant , modulo which all computations will be performed.
#define MOD 100000000
The function gcd computes the greatest common divisor of two numbers and .
long long gcd(long long a, long long b)
{
return (!b) ? a : gcd(b, a % b);
}Declare the Matrix structure — a 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_) {}
};The function multiply multiplies two 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
);
}The function power implements binary exponentiation of the matrix to the power .
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;
}The function fib computes the -th Fibonacci number modulo 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)
}The main part of the program. Read the input data, compute, and print the value of .
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:
From it, the following special cases directly follow:
if , then .
if , then .
These formulas allow Fibonacci numbers to be computed using a "divide and conquer" approach, reducing the computation of to values with indices approximately half as large.
The base cases are handled separately:
With this approach, the recursion depth is proportional to , and the time complexity of the algorithm is .
Declare the constant , modulo which all computations will be performed.
#define MOD 100000000
Declare a variable 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 and .
long long gcd(long long a, long long b)
{
return (!b) ? a : gcd(b,a % b);
}The function fib computes the -th Fibonacci number modulo .
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 has already been computed and stored in , it is returned immediately without recomputation.
if (F[n]) return F[n];
Next, we use the decomposition of the number into:
— odd case: .
— even case: .
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 .
while(scanf("%lld %lld",&a,&b) == 2)
{
d = gcd(a,b);
printf("%lld\n",fib(d));
}As is well known, the Fibonacci numbers are defined as follows:
Given two integers and , compute the sum:
Input. Each line represents a separate test case and contains two integers and .
Output. For each test case, print on a separate line the value of modulo .
1 1 3 5 10 1000
1 10 625271457
Theorem. For the Fibonacci numbers, the following formula holds:
Proof. We prove the statement by induction.
Base case. For we have:
That is, , which is true.
Inductive step. Assume that:
Then:
which completes the proof
Then the desired sum
can be computed as
Computing Fibonacci numbers using Binet's formula
Consider the generating function for the Fibonacci numbers ():
From this it follows that:
Let us decompose the generating function into partial fractions. First, find the roots of the denominator:
where
Now represent the generating function as:
Solving the system, we obtain:
Taking into account that
the generating function can be rewritten as:
But since
equating the coefficients of gives:
Computing Fibonacci Numbers Using an Identity
For the Fibonacci numbers, the following identity is known:
From it, the following special cases follow directly:
if , then
if , then
These formulas make it possible to compute Fibonacci numbers using a divide-and-conquer approach, reducing the computation of to values with indices approximately half as large.
The base cases are handled separately:
With this approach, the recursion depth is proportional to , and the time complexity of the algorithm is .
Example
Let us compute some Fibonacci numbers using Binet’s formula, working in the extended field with a large modulus .
Let us illustrate the application of the formulas with an example:
if , then
if , then
Declare the constant , which will be used as the modulus for all computations.
#define MOD 1000000007
Declare a variable of type to store (memoize) already computed Fibonacci numbers.
map<long long, long long> fib;
The function f computes the -th Fibonacci number modulo .
long long f(long long n)
{
if (n == 0) return 0;
if (n == 1) return 1;
if (n == 2) return 1;If the -th Fibonacci number has already been computed and stored in , it is returned immediately without recomputation.
if (fib[n]) return fib[n];
Next, we decompose the number as follows:
— odd case: .
— even case: .
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 , which will be used as the modulus for all computations.
#define MOD 1000000007
Declare the structure to store a number of the form .
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 . The function mult returns the product of the numbers and .
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;
}The function pow performs exponentiation of , where is a number in the field .
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;
}The function modpow computes the value of .
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;
}The function fib computes the -th Fibonacci number.
long long fib(long long n)
{Initialize the constants and .
Num phi(1, 1); Num psi(1, MOD - 1);
Compute the powers and .
Num A = pow(phi, n); Num B = pow(psi, n);
Since
compute the numerator and denominator separately.
Note that (so ), and the coefficient of in the numerator is .
long long numerator = (A.y - B.y + MOD) % MOD;
Compute in the denominator.
long long denom = pow(2, n);
Both the numerator and the denominator contain a factor of . Cancel this factor, leaving the result to be computed as:
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);Generate the -th Fibonacci string, which is defined by the following recurrence relation:
;
;
, where the "" denotes string concatenation.
For example:
Input. One integer .
Output. Print the -th Fibonacci string.
3
bab
5
babbabab
Implement a recursive function that generates the -th Fibonacci string.
The function f returns the -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 and print the -th Fibonacci string.
cin >> n; cout << f(n) << endl;
Algorithm implementation — without STL
The function f returns the -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);
}The main part of the program. Read the input value and print the -th Fibonacci string.
scanf("%d",&n);
f(n); printf("\n");While the students are taking an exam, the teachers are playing Mafia. There are teachers sitting around a round table. The host must deal ace cards to some of them (the number of aces can be arbitrary, including ) — 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 sitting around the table.
Output. Print one integer — the number of ways to deal the cards.
1
2
2
3
Let be the number of ways to deal cards to teachers arranged in a line (the first and the last are not considered adjacent). This problem is equivalent to counting binary sequences of length consisting of s and s in which no two s are adjacent. The solution is given by the Fibonacci sequence defined by the following recurrence relation:
Let be the number of ways to deal cards to teachers seated in a circle.
If the first teacher does not receive an ace, then the remaining teachers can be dealt aces in 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 teachers can be dealt aces in ways.
Thus, we obtain the following relation:
Example
For , we need the value . It can be found from the equality , which gives
Therefore,
The base cases are as follows:
Declare an array 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 .
scanf("%d", &n);Compute the answer .
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);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 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 .
Output. Print the number of safe ways to build the tower.
1
2
2
3
Each empty box is represented by , and each TNT box by . The task is to determine the number of strings of length , consisting of s and s, such that no two s are adjacent.
The answer to the problem will be the Fibonacci number :
Example
Consider all possible towers of heights . Each corresponds to a sequence of s and s. There are:
two towers of height : ;
three towers of height : ;
five towers of height : ;
Declare an array.
#define MAX 45 int fib[MAX];
Fill the elements of the 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 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 -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);
}The main part of the program. Read the input value of and print the result.
scanf("%d", &n);
memset(fib, -1, sizeof(fib));
printf("%d\n", f(n));A bee, moving inside a honeycomb, can move as shown in the figure:
by moves and — from the upper row,
by move — from the lower row.

Input. The number of hexagons 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.
1
1
3
2
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 hexagons, the rightmost hexagon in the upper row will have number .
Let denote the number of ways to reach the hexagon numbered from the first hexagon. Since the bee needs to reach hexagon number , the answer to the problem will be .
Now, let's consider the transitions between hexagons.
Let hexagon be in the upper row (an odd number). Then the bee can reach it either from hexagon or from hexagon . Therefore, for odd the following recurrence holds:
Let hexagon be in the lower row (an even number). In this case, there is only one possible transition — from the previous hexagon:
To implement the recursion, we need to set the initial values:
These can be easily verified directly from the bee's movement diagram.
Declare an array.
#define MAX 100 int fib[MAX];
Fill the elements of the 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 and print the answer .
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);
}The main part of the program. Read the input value .
scanf("%d",&n);Compute and print the answer.
memset(fib,-1,sizeof(fib));
printf("%d\n",f(2*n-1));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 . 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 . 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 .
Output. Print the expected value as a fraction , where and are coprime positive integers.
1
1/1
4
2/1
A password (a string of length ) is considered secure if it does not contain two consecutive zeros. The number of such strings is equal to the Fibonacci number , defined as follows:
(the strings , ),
(the strings , , ),
For example, the first Fibonacci numbers are:
The total number of binary strings of length is . Therefore, the expected number of randomly generated strings required to obtain a secure one is equal to
This fraction should be reduced by dividing the numerator and the denominator by their greatest common divisor.
Example
For , the answer is .
For , the answer is .
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 .
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:
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);The flag consists of 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 stripes?
Input. One integer — the number of stripes on the flag.
Output. Print the number of ways to color a flag with stripes. The answer should be given modulo .
3
4
Let:
be the number of ways to color a flag with stripes, starting with a red stripe;
be the number of ways to color a flag with stripes, starting with a white stripe;
Let’s consider how to compute the function :
If the stripe following the red one is white, then the remaining flag of length can be colored in 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 can be colored in ways;
Thus, we obtain the following equality:
By analogous reasoning, we obtain:
The initial conditions for the first recurrence are obvious:
: A flag consisting of one stripe and starting with red can be colored in exactly one way — .
: 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 .
Similarly,
Both functions and define Fibonacci numbers:
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
Declare the constants.
#define MAX 1000001 #define MOD 1000000007
Declare an array to store the Fibonacci numbers.
long long fib[MAX];
Read the input value .
scanf("%d", &n);Fill the array 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);Find the number of ways to completely tile a rectangle of size with dominoes of size . Coverings that coincide with themselves under symmetries (rotations or reflections) are considered different.
Input. One integer .
Output. Print the number of ways to tile the rectangle with dominoes.
1
1
4
5
Let denote the number of ways to tile a rectangle with . dominoes. It is clear that
, one vertical domino;
, either two vertical dominoes or two horizontal dominoes.

Consider the algorithm for computing :
we can place one domino vertically, after which the remaining rectangle of length can be tiled in ways,
or we can place two dominoes horizontally, after which the remaining rectangle of length can be tiled in ways.
Thus, we obtain the recurrence relation:

Therefore, is a Fibonacci number.
Since , 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();
}
}Python implementation
Increase the limit to the required value (for example, digits).
import sys sys.set_int_max_str_digits(100000)
Read the input value .
n = int(input())
Process the base cases.
if n == 1: print(1) elif n == 2: print(2) else:
Compute the -th Fibonacci number.
f1, f2 = 1, 2
for i in range(n - 2):
temp = f1 + f2
f1, f2 = f2, tempPrint the answer.
print(f2)
The Fibonacci numbers are defined as follows:
Compute the -th Fibonacci number.
Input. The first line contains the number of test cases . Each of the next lines contains one integer .
Output. For each test case, print the corresponding Fibonacci number on a separate line.
5 1 2 3 4 5
1 1 2 3 5
Since , computing requires the use of arbitrary-precision arithmetic or, for example, programming languages such as Java or Python.
Сompute the Fibonacci numbers from to and store them in an array . Then, for each input value print .
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 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();
}
}Python implementation
Initialize the first two Fibonacci numbers: .
f1, f2 = 1, 1
Create a list to store the Fibonacci numbers. The value is added intentionally so that the indexing matches the problem statement.
fib = [0, f1, f2]
Compute the Fibonacci numbers up to .
for i in range(10000): add = f1 + f2 fib.append(add) f1, f2 = f2, add
Read the number of test cases .
t = int(input()) for i in range(t):
Read the input value and print .
n = int(input()) print(fib[n])
For the given integers , find the value of the expression:
Print the result as two numbers and such that
Input. Five integers are given. It is known that:
is a prime number,
,
,
Output. Print two integers and — the coefficients of and respectively, modulo .
Note. You should work in the extended field:
Operation rules:
Addition
Multiplication
All operations are performed modulo .
Examples. In the first example:
In the second example:
2 1 5 2 17
9 4
3 2 5 10 17
1 2
All computations should be performed in the extended field:
Operation rules:
Addition
Multiplication
After defining the multiplication operation, elements of the field can be raised to a power using the standard binary exponentiation method in time. This makes it possible to compute .
Example
In the first example
Let us consider the second example:
Let . We'll compute its powers step by step:
Now we can compute the result:
Let us define a structure to store numbers of the form .
struct Num
{
long long x, y; // x + y*sqrt(c)
};Let's implement multiplication in the field . The function mult returns the product of two numbers and .
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;
}The function pow implements exponentiation, computing , where is a number in the field .
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;
}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 .
Num start = { a % p, b % p };Compute and print the answer .
Num ans = pow(start, n);
printf("%lld %lld\n", ans.x, ans.y);For the given integers , compute the value of the sum:
Print the result as two numbers and such that
Input. Five integers are given. It is known that:
is a prime number,
,
,
Output. Print two integers and — the coefficients of and respectively, modulo .
Note. You should work in the extended field:
Operation rules:
Addition
Multiplication
All operations are performed modulo .
Examples. In the first example:
In the second example:
2 1 5 2 17
9 4
3 2 5 10 17
1 2
All computations should be performed in the extended field:
Operation rules:
Addition
Multiplication
Let . Then the required sum is a finite geometric progression:
It remains to perform the division by in the field :
Example
In the first example
Let's compute this example using the formula:
In the second example
The function modpow computes the value .
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;
}Let's define a structure to store numbers of the form .
struct Num
{
long long x, y; // x + y*sqrt(c)
};Let's implement addition in the field . The function add returns the sum of two numbers and .
Num add(Num& a, Num& b)
{
Num res;
res.x = (a.x + b.x) % p;
res.y = (a.y + b.y) % p;
return res;
}Let's implement subtraction in the field . The function sub returns the difference of two numbers and .
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;
}Let's implement multiplication in the field . The function mult returns the product of two numbers and .
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;
}The function pow implements exponentiation of , where is an element of the field .
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;
}The function divide implements division in the field . It returns the quotient of the numbers and . The division is performed by multiplying by the conjugate:
Num divide(Num& a, Num& b)
{Let .
Num conj = { b.x, (p - b.y) % p };Compute .
Num n = mult(a, conj);
Compute .
long long denom =
((b.x * b.x) % p - ((b.y * b.y) % p * c) % p + p) % p;Compute the multiplicative inverse and return .
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 and the multiplicative identity of the field .
Num x = { a % p, b % p };
Num one = { 1, 0 };Compute , .
Num num = pow(x, n + 1); num = sub(num, one); Num denom = sub(x, one);
Compute and print the answer .
Num res = divide(num, denom);
printf("%lld %lld\n", res.x, res.y);Given two integers and , compute the value:
where is the -th Fibonacci number.
The Fibonacci sequence is defined as follows:
Since the answer can be very large, print it modulo .
Input. One line contains two integers and where:
is the number of terms in the sum,
is the exponent applied to each Fibonacci number.
Output. Print one integer — the value of the sum:
4 1
7
5 10
9825700
Consider the Binet formula:
where
Then:
Now we sum over :
The inner sum is an ordinary geometric progression:
To eliminate and avoid working with floating-point numbers, all computations will be performed in the extended field of the form modulo .
Example
Consider summing powers with .
Then the required sum is:
Declare a constant for the modulus .
#define MOD 1000000007
We'll store the values of binomial coefficients in the array .
vector<long long> Cnk;
To implement arithmetic in the field , define a structure . This structure represents numbers of the form .
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 .
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 .
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
);
}The function pw implements binary exponentiation in the field , where the exponent 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;
}The function pw implements fast binary exponentiation to compute modulo .
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;
}The function inv computes the multiplicative inverse of an element in the field .
If
then its inverse element is given by
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
);
}The function divide implements division in the field :
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 and store them in the array . Note that
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;
}Compute .
long long inv2 = (MOD + 1) / 2;
Initialize the constants: and .
Num phi(inv2, inv2); Num psi(inv2, MOD - inv2);
Compute .
Num ratio = divide(psi, phi);
Initialize the constants and in the field .
Num one(1, 0); Num minus_one(MOD - 1, 0);
The answer will be accumulated in the variable .
Num res(0, 0);
Initialize . Then, in the loop, we will multiply this value by , obtaining
Num t = pw(phi, k);
In the variable we compute the sum
The required sum contains terms. Therefore, we perform iterations.
for (j = 0; j <= k; j++)
{
Num term;At this point . Compute the sum of the geometric progression:
However, the case should be handled separately, because the formula for the sum of a geometric progression contains division by . When the sum takes the form: ( times) and is equal to .
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)
}Compute .
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 to the result .
res = add(res, term);
Multiply by , obtaining .
t = mult(t, ratio); }
It remains to divide by .
Num sqrt5(0, 1); Num sqrt5k = pw(sqrt5, k); res = divide(res, sqrt5k);
Print the answer.
printf("%lld\n", res.x);