Challenge: Fibonacci LCM
Subdomeniu: Number Theory (number-theory)
Scor cont: 80.0 / 80
Submission status: Accepted
Submission score: 1.0
Submission ID: 464735141
Limbaj: cpp14
Link challenge: https://www.hackerrank.com/challenges/fibonacci-lcm/problem
Cerinta
After Derek (of district 5) discovered how to compute the greatest common divisor (gcd) of Fibonacci numbers, he now tried to answer the next obvious question: how does one compute the *least common multiple* (lcm) of Fibonacci numbers? Unfortunately, Derek found out that this wasn't as easy as the original problem, so he asked you to answer it for him.
The Fibonacci numbers are defined as:
$$F_1 = F_2 = 1$$
$$F_n = F_{n-1} + F_{n-2}$$
Given $N$ integers $a_1, a_2, \ldots, a_N$, find $\text{lcm}(F_{a_1},F_{a_2},\ldots,F_{a_N})$, and give your answer modulo $10^9+7$.
**Input Format**
The first line of input contains $N$.
Each of the next $N$ lines contains a number: the $i^{\text{th}}$ line contains $a_i$.
**Constraints**
$1 \le N \le 100$
$1 \le a_i \le 10^9$
**Output Format**
Print a single integer, which is the least common multiple of the $F_{a_i}$, modulo $10^9+7$.
**Sample Input**
5
1
3
3
6
9
**Sample Output**
136
**Explanation**
$\text{lcm}(F_1,F_3,F_3,F_6,F_9) = \text{lcm}(1,2,2,8,34) = 136$
Cod sursa
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 9, mod= 1e9 + 7;
int power(long long n, long long k) {
int ans = 1 % mod; n %= mod; if (n < 0) n += mod;
while (k) {
if (k & 1) ans = (long long) ans * n % mod;
n = (long long) n * n % mod;
k >>= 1;
}
return ans;
}
int fib(long long n) {
assert (n >= 0);
if (n <= 1) return n;
int a = 0;
int b = 1;
long long i = 1ll << (63 - __builtin_clzll(n) - 1);
for (; i; i >>= 1) {
int na = (a *(long long) a + b *(long long) b) % mod;
int nb = (2ll * a + b) * b % mod;
a = na;
b = nb;
if (n & i) {
int c = a + b; if (c >= mod) c -= mod;
a = b;
b = c;
}
}
return b;
}
map<vector<int>, int> dp;
/**
O((max number of divisors of a[i]) * n * log(max a[i])) but faster in practice
lcm(a1, a2, ... an)
= lcm(lcm(a1, ..., a[n-1]), an)
= lcm(a1, ..., a[n-1]) * an / gcd(lcm(a1, ..., a[n-1]), an)
= lcm(a1, ..., a[n-1]) * an / lcm(gcd(a1, an), ... gcd(a[n-1], an))
**/
int yo(vector<int> a) {
sort(a.rbegin(), a.rend());
while (!a.empty() && a.back() <= 2) a.pop_back();
a.resize(unique(a.begin(), a.end()) - a.begin());
if (a.empty()) return 1;
if (a.size() == 1) return fib(a[0]);
if (dp.count(a)) return dp[a];
vector<int> b(a.begin(), a.end() - 1);
long long res = yo(b);
for (int i = 0; i < b.size(); ++i) b[i] = __gcd(b[i], a.back());
res = res * fib(a.back()) % mod * power(yo(b), mod - 2) % mod;
dp[a] = res;
return res;
}
int32_t main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
int n; cin >> n;
vector<int> a(n);
for (auto &x: a) cin >> x;
cout << yo(a) << '\n';
return 0;
}
//https://www.hackerrank.com/contests/infinitum10/challenges/fibonacci-lcm/problem
HackerRank Number Theory – Fibonacci LCM
