Calculating mod m for large Fibonacci numbers - c++

I am getting two warning (narrowing conversion && control may reach end of non-void function) with the following code. The code compiles however, when I run it it gives this message : Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
The code is compiled using CLion on Ubuntu
// calculate F(n) mod m
#include <iostream>
#include <cmath>
long long Fiobonacci(long long n) { // Fast calculation of Fibonacci number using 'fast doubling'
if (n == 0)
return 0;
else if (n % 2 == 0)
return Fiobonacci(n / 2) * (2 * Fiobonacci(n / 2 + 1) - Fiobonacci(n / 2));
else
return std::pow(Fiobonacci((n + 1) / 2), 2) + std::pow(Fiobonacci((n - 1) / 2), 2);
}
long long GetPissanoPeriod(long long m){
for (long long i = 0; i <= 6 * m ; ++i){
if (Fiobonacci(i) % m == 0){ // if an element is zero it might be followed by a 1
if(Fiobonacci(i+1) % m == 1)
return i+1;
}
}
}
int main() {
long long n, m;
std::cin >> n >> m;
long long period = GetPissanoPeriod(m);
long long res = Fiobonacci(n % period) % m;
std::cout << res << 'n';
}

See the modified code below.
#include <iostream>
#include <cmath>
using namespace std;
long long pow2(long long x)
{
return x * x;
}
long long Fibonacci(long long n) { // Fast calculation of Fibonacci number using 'fast doubling'
if (n == 0)
return 0;
else if(n <= 2)
return 1;
else if (n % 2 == 0)
return Fibonacci(n / 2) * (2 * Fibonacci(n / 2 + 1) - Fibonacci(n / 2));
else
return pow2(Fibonacci((n/2 + 1) / 2), 2) + pow2(Fibonacci((n / 2)), 2);
}
long long GetPisanoPeriod(long long m){
for (long long i = 2; i <= m * m ; ++i){
if (Fibonacci(i) % m == 0){ // if an element is zero it might be followed by a 1
if(Fibonacci(i+1) % m == 1){
return i - 1;
}
}
}
return 1;
}
int main() {
long long n, m;
std::cin >> n >> m;
long long period = GetPisanoPeriod(m);
long long res = Fibonacci(n % period) % m;
std::cout << "res" << res<<endl;
}
control may reach end of non-void function error is due to not returning value from GetPisanoPeriod. as pointed out by #JaMiT
The segmentation fault was due to the incorrect termination condition of function Fibonacci.
Fibonacci series is defined as below.
Fn = Fn-1 + Fn-2
with seed values
F0 = 0 and F1 = 1
Meaning there should be a termination condition for n = 0 and n = 1.
For n = 2 You don't have to call recursion can simply return 1.
Other than that, There were corrections in Fibonacci calculation formula as you can see.
In GetPisanoPeriod The control has to start from 2. otherwise it would always return 0.

Related

Want to minimize my code so it consumes time less than 1 sec. It uses concept of modular exponentiation .Correct output but exceeding time limit

The below code is to calculate 2^n where n is equal to 1 <= n <= 10^5. So to calculate such large numbers I have used concept of modular exponentian. The code is giving correct output but due to large number of test cases it is exceeding the time limit. I am not getting a way to minimize the solution so it consumes less time. As the "algo" function is called as many times as the number of test cases. So I want to put the logic used in "algo" function in the main() function so it consumes time less than 1 sec and also gives the correct output. Here "t" represents number of test cases and it's value is 1 <= t <= 10^5.
Any suggestions from your side would be of great help!!
#include<iostream>
#include<math.h>
using namespace std;
int algo(int x, int y){
long m = 1000000007;
if(y == 0){
return 1;
}
int k = algo(x,y/2);
if (y % 2 == 1){
return ((((1ll * k * k) % m) * x) % m);
} else if (y % 2 == 0){
return ((1ll * k * k) % m);
}
}
int main(void)
{
int n, t, k;
cin>>t; //t = number of test cases
for ( k = 0; k < t; k++)
{
cin >> n; //power of 2
cout<<"the value after algo is: "<<algo(2,n)<<endl;
}
return 0;
}
You can make use of binary shifts to find powers of two
#include <iostream>
using namespace std;
int main()
{
unsigned long long u = 1, w = 2, n = 10, p = 1000000007, r;
//n -> power of two
while (n != 0)
{
if ((n & 0x1) != 0)
u = (u * w) % p;
if ((n >>= 1) != 0)
w = (w * w) % p;
}
r = (unsigned long)u;
cout << r;
return 0;
}
This is the function that I often use to calculate
Any integer X raised to power Y modulo M
C++ Function to calculate (X^Y) mod M
int power(int x, int y, const int mod = 1e9+7)
{
int result = 1;
x = x % mod;
if (x == 0)
return 0;
while (y > 0)
{
if (y & 1)
result = ( (result % mod) * (x % mod) ) % mod;
y = y >> 1; // y = y / 2
x = ( (x % mod) * (x % mod) ) % mod;
}
return result;
}
Remove the Mod if you don't want.
Time Complexity of this Function is O(log2(Y))
There can be a case of over flow so use int , long , long long etc as per your need.
Well your variables won't sustain the boundary test cases, introducing 2^10000, 1 <= n <= 10^5. RIP algorithms
19950631168807583848837421626835850838234968318861924548520089498529438830221946631919961684036194597899331129423209124271556491349413781117593785932096323957855730046793794526765246551266059895520550086918193311542508608460618104685509074866089624888090489894838009253941633257850621568309473902556912388065225096643874441046759871626985453222868538161694315775629640762836880760732228535091641476183956381458969463899410840960536267821064621427333394036525565649530603142680234969400335934316651459297773279665775606172582031407994198179607378245683762280037302885487251900834464581454650557929601414833921615734588139257095379769119277800826957735674444123062018757836325502728323789270710373802866393031428133241401624195671690574061419654342324638801248856147305207431992259611796250130992860241708340807605932320161268492288496255841312844061536738951487114256315111089745514203313820202931640957596464756010405845841566072044962867016515061920631004186422275908670900574606417856951911456055068251250406007519842261898059237118054444788072906395242548339221982707404473162376760846613033778706039803413197133493654622700563169937455508241780972810983291314403571877524768509857276937926433221599399876886660808368837838027643282775172273657572744784112294389733810861607423253291974813120197604178281965697475898164531258434135959862784130128185406283476649088690521047580882615823961985770122407044330583075869039319604603404973156583208672105913300903752823415539745394397715257455290510212310947321610753474825740775273986348298498340756937955646638621874569499279016572103701364433135817214311791398222983845847334440270964182851005072927748364550578634501100852987812389473928699540834346158807043959118985815145779177143619698728131459483783202081474982171858011389071228250905826817436220577475921417653715687725614904582904992461028630081535583308130101987675856234343538955409175623400844887526162643568648833519463720377293240094456246923254350400678027273837755376406726898636241037491410966718557050759098100246789880178271925953381282421954028302759408448955014676668389697996886241636313376393903373455801407636741877711055384225739499110186468219696581651485130494222369947714763069155468217682876200362777257723781365331611196811280792669481887201298643660768551639860534602297871557517947385246369446923087894265948217008051120322365496288169035739121368338393591756418733850510970271613915439590991598154654417336311656936031122249937969999226781732358023111862644575299135758175008199839236284615249881088960232244362173771618086357015468484058622329792853875623486556440536962622018963571028812361567512543338303270029097668650568557157505516727518899194129711337690149916181315171544007728650573189557450920330185304847113818315407324053319038462084036421763703911550639789000742853672196280903477974533320468368795868580237952218629120080742819551317948157624448298518461509704888027274721574688131594750409732115080498190455803416826949787141316063210686391511681774304792596709376
Fear not my friend, someone did tried to solve the problem https://www.quora.com/What-is-2-raised-to-the-power-of-50-000, you are looking for Piyush Michael's answer , here is his sample code
#include <stdio.h>
int main()
{
int ul=16,000;
int rs=50,000;
int s=0,carry[ul],i,j,k,ar[ul];
ar[0]=2;
for(i=1;i<ul;i++)ar[i]=0;
for(j=1;j<rs;j++)
{for(k=0;k<ul;k++)carry[k]=0;
for(i=0;i<ul;i++)
{ar[i]=ar[i]*2+carry[i];
if(ar[i]>9)
{carry[i+1]=ar[i]/10;
ar[i]=ar[i]%10;
}
}
}
for(j=ul-1;j>=0;j--)printf("%d",ar[j]);
for(i=0;i<ul-1;i++)s+=ar[i];
printf("\n\n%d",s);
}

greatest divisor of a number and prime factors relation

Question is as follows :
Given two numbers n and k. For each number in the interval [1, n], your task is to calculate its largest divisor that is not divisible by k. Print the sum of all these divisors.
Note: k is always a prime number.
t=3*10^5,1<=n<=10^9, 2<=k<=10^9
My approach toward the question:
for every i in range 1 to n, the required divisors is i itself,only when that i is not a multiple of k.
If that i is multiple of k, then we have to find the greatest divisor of a number and match with k. If it does not match, then this divisor is my answer. otherwise, 2nd largest divisor is my answer.
for example,take n=10 and k=2, required divisors for every i in range 1 to 10 is 1, 1, 3, 1, 5, 3, 7, 1, 9, 5. sum of these divisors are 36. So ans=36.
My code,which works for a few test cases and failed for some.
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
ll div2(ll n, ll k) {
if (n % k != 0 || n == 1) {
return n;
}
else {
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
ll aa = n / i;
if (aa % k != 0) {
return aa;
}
}
}
}
return 1;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--) {
ll n, k;
cin >> n >> k;
ll sum = 0, pp;
for (pp = 1; pp <= n; pp++) {
//cout << div2(pp, k);
sum = sum + div2(pp, k);
}
cout << sum << '\n';
}
}
Can someone help me where I am doing wrong or suggest me some faster logic to do this question as some of my test cases is showing TIME LIMIT EXCEED
after looking every possible explanation , i modify my code as follows:
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--) {
ll n, i;
ll k, sum;
cin >> n >> k;
sum = (n * (n + 1)) / 2;
for (i = k; i <= n; i = i + k) {
ll dmax = i / k;
while (dmax % k == 0) {
dmax = dmax / k;
}
sum = (sum - i) + dmax;
}
cout << sum << '\n';
}
}
But still it is giving TIME LIMIT EXCEED for 3 test cases. Someone please help.
Like others already said, look at the constraints: t=3*10^5,1<=n<=10^9, 2<=k<=10^9.
If your test has a complexity O(n), which computing the sum via a loop has, you'll end up doing a t * n ~ 10^14. That's too much.
This challenge is a math one. You'll need to use two facts:
as you already saw, if i = j * k^s with j%k != 0, the largest divisor is j;
sum_{i=1}^t i = (t * (t+1)) / 2
We start with
S = sum(range(1, n)) = n * (n+1) / 2
then for all number of the form k * x we added too much, let's correct:
S = S - sum(k*x for x in range(1, n/k)) + sum(x for x in range(1, n/k))
= S - (k - 1) * (n/k) * (n/k + 1) / 2
continue for number of the form k^2 * x ... then k^p * x until the sum is empty...
Ok, people start writing code, so here's a small Python function:
def so61867604(n, k):
S = (n * (n+1)) // 2
k_pow = k
while k_pow <= n:
up = n // k_pow
S = S - (k - 1) * (up * (up + 1)) // 2
k_pow *= k
return S
and in action here https://repl.it/repls/OlivedrabKeyProjections
In itself this is more of a mathematical problem:
If cur = [1..n], as you have already noticed, the largest divisor = dmax = cur is, if cur % k != 0, otherwise dmax must be < cur. From k we know that it is at most divisible into other prime numbers... Since we want to make sure that dmax is not divisible by k we can do this with a while loop... whereby this is certainly also more elegantly possible (since dmax must be a prime number again due to the prime factorization).
So this should look like this (without guarantee just typed down - maybe I missed something in my thinking):
#include <iostream>
int main() {
unsigned long long n = 10;
unsigned long long k = 2;
for (auto cur_n = decltype(n){1}; cur_n <= n; cur_n++)
{
if (cur_n % k != 0) {
std::cout << "Largest divisor for " << cur_n << ": " << cur_n << " (SELF)" << std::endl;
} else {
unsigned long long dmax= cur_n/k;
while (dmax%k == 0)
dmax= dmax/k;
std::cout << "Largest divisor for " << cur_n << ": " << dmax<< std::endl;
}
}
}
I wonder if something like this is what One Lyner means.
(Note, this code has two errors in it, which are described in the comments, as well as can be elucidated by One Lyner's new code.)
C++ code:
#include <vector>
#include <iostream>
using namespace std;
#define ll long long int
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--) {
ll n;
ll k, _k, result;
vector<ll> powers;
cin >> n >> k;
result = n * (n + 1) / 2;
_k = k;
while (_k <= n) {
powers.push_back(_k);
_k = _k * k;
}
for (ll p : powers) {
ll num_js = n / p;
result -= num_js * (num_js + 1) / 2 * (p - 1);
int i = 0;
while (p * powers[i] <= n) {
result += powers[i] * (p - 1);
i = i + 1;
}
}
cout << result << '\n';
}
}

Big primes loop with GMP library C++

It's the first time that I use the gmp library, so I'm really lost, I've found a code implementing the "miller rabin primality test" in c++ but I wanted to be able to apply it to integers with arbitrary precision so I installed the GMP library.
The problem is, I've got no idea of how GMP library actually works (I've read trough a few pages of the manual but I understand very little about it also since I haven't even studied object oriented programming), I want to adapt the primality test to be able to input integers 'num' of about 1000-2000 digits, here's the code:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <gmpxx.h>
#include <gmp.h>
#define ll long long
using namespace std;
/*
* calculates (a * b) % c taking into account that a * b might overflow
*/
ll mulmod(ll a, ll b, ll mod)
{
ll x = 0,y = a % mod;
while (b > 0)
{
if (b % 2 == 1)
{
x = (x + y) % mod;
}
y = (y * 2) % mod;
b /= 2;
}
return x % mod;
}
/*
* modular exponentiation
*/
ll modulo(ll base, ll exponent, ll mod)
{
ll x = 1;
ll y = base;
while (exponent > 0)
{
if (exponent % 2 == 1)
x = (x * y) % mod;
y = (y * y) % mod;
exponent = exponent / 2;
}
return x % mod;
}
/*
* Miller-Rabin primality test, iteration signifies the accuracy
*/
bool Miller(ll p,int iteration)
{
if (p < 2)
{
return false;
}
if (p != 2 && p % 2==0)
{
return false;
}
ll s = p - 1;
while (s % 2 == 0)
{
s /= 2;
}
for (int i = 0; i < iteration; i++)
{
ll a = rand() % (p - 1) + 1, temp = s;
ll mod = modulo(a, temp, p);
while (temp != p - 1 && mod != 1 && mod != p - 1)
{
mod = mulmod(mod, mod, p);
temp *= 2;
}
if (mod != p - 1 && temp % 2 == 0)
{
return false;
}
}
return true;
}
//Main
int main()
{
int w=0;
int iteration = 5;
mpz_t num;
cout<<"Enter integer to loop: ";
cin>>num;
if (num % 2 == 0)
num=num+1;
while (w==0) {
if (Miller(num, iteration)) {
cout<<num<<" is prime"<<endl;
w=1;
}
else
num=num+2;
}
system ("PAUSE");
return 0;
}
(If I define num to be 'long long' the program works just fine, but I have no idea how I should adapt the whole thing to "match" num being defined as 'mpz_t' instead, also I didn't mention it but the program basically takes an initial integer value and loops it by adding 2 if the integer is composite until it becomes a prime number)

Calculate Huge Fibonacci number modulo M in C++

Problem statement : Given two integers n and m, output Fn mod m (that is, the remainder of Fn when divided by m).
Input Format. The input consists of two integers n and m given on the same line (separated by a space).
Constraints. 1 ≤ n ≤ 10^18, 2 ≤ m ≤ 10^5
Output Format. Output Fn mod m.
I tried the following program and it didn't work. The method pi is returning the right Pisano period though for any number as per http://webspace.ship.edu/msrenault/fibonacci/fiblist.htm
#include <iostream>
long long pi(long long m) {
long long result = 2;
for (long long fn2 = 1, fn1 = 2 % m, fn = 3 % m;
fn1 != 1 || fn != 1;
fn2 = fn1, fn1 = fn, fn = (fn1 + fn2) % m
) {
result++;
}
return result;
}
long long get_fibonaccihuge(long long n, long long m) {
long long periodlength = pi(m);
int patternRemainder = n % periodlength;
long long *sum = new long long[patternRemainder];
sum[0] = 0;
sum[1] = 1;
for (int i = 2; i <= patternRemainder; ++i)
{
sum[i] = sum[i - 1] + sum[i - 2];
}
return sum[patternRemainder] % m;
}
int main() {
long long n, m;
std::cin >> n >> m;
std::cout << get_fibonaccihuge(n, m) << '\n';
}
The exact program/logic is working well in python as expected. What's wrong withthis cpp program ? Is it the data types ?
Performing 10^18 additions isn't going to be very practical. Even on a teraflop computer, 10^6 seconds is still 277 hours.
But 10^18 ~= 2^59.8 so there'll be up to 60 halving steps.
Calculate (a,b) --> (a^2 + b^2, 2ab + b^2) to go from (n-1,n)th to (2n-1,2n)th consecutive Fibonacci number pairs in one step.
At each step perform the modulus calculation for each operation. You'll need to accommodate integers up to 3*1010 &leq; 235 in magnitude (i.e. up to 35 bits).
(cf. a related older answer of mine).
This was my solution for this problem, it works well and succeeded in the submission test ...
i used a simpler way to get the pisoano period ( pisano period is the main tricky part in this problem ) ... i wish to be helpful
#include <iostream>
using namespace std;
unsigned long long get_fibonacci_huge_naive(unsigned long long n, unsigned long long m)
{
if (n <= 1)
return n;
unsigned long long previous = 0;
unsigned long long current = 1;
for (unsigned long long i = 0; i < n - 1; ++i)
{
unsigned long long tmp_previous = previous;
previous = current;
current = tmp_previous + current;
}
return current % m;
}
long long get_pisano_period(long long m)
{
long long a = 0, b = 1, c = a + b;
for (int i = 0; i < m * m; i++)
{
c = (a + b) % m;
a = b;
b = c;
if (a == 0 && b == 1)
{
return i + 1;
}
}
}
unsigned long long get_fibonacci_huge_faster(unsigned long long n, unsigned long long m)
{
n = n % get_pisano_period(m);
unsigned long long F[n + 1] = {};
F[0] = 0;
F[-1] = 1;
for (int i = 1; i <= n; i++)
{
F[i] = F[i - 1] + F[i - 2];
F[i] = F[i] % m;
}
return F[n];
}
int main()
{
unsigned long long n, m;
std::cin >> n >> m;
std::cout << get_fibonacci_huge_faster(n, m) << '\n';
}

C++ Recursion Segmentation Fault

#include <iostream>
using namespace std;
int findSumofOdds(int n);
int main()
{
int n = 88;
int x;
x = findSumofOdds(n);
cout << x << endl;
return 0;
}
int findSumofOdds(int n)
{
if (n != 1)
{
if( n % 2 == 0)
n = (n - 1);
return(findSumofOdds(n-1) + 1);
}
else
return 1;
}
Why isn't this recursion working? It tries to run and then crashes. Please let me know. My teacher said that it would work but doesn't.
When n is even, you are decrementing n by two. If it skips over n == 1, it will recurse until it causes a stack overflow. Since n starts out at 88, that's what's happening.
int findSumofOdds(int n)
{
if (n != 1)
{
if( n % 2 == 0)
n = (n - 1); // <== first decrement
return(findSumofOdds(n-1) + 1); // <== second decrement
}
else
return 1;
}
Also, you seem to be counting the number of odd numbers, not adding them. My guess is that you actually want something like:
int findSumofOdds(int n)
{
if (n != 1)
{
if( n % 2 == 0)
return(findSumofOdds(n - 1));
return(findSumofOdds(n-1) + n); // or + 1 to just count
}
else
return 1;
}
If you want to practice recursion, that's fine. But there's a much simpler way to write a function to sum the odd numbers up to and including n:
int fundSumofOdds(int n) {
n = (n + 1) / 2;
return n * n;
}
This is because there's a general formula:
1 + 3 + 5 + ... + 2n-1 = n2
You have to make it
if (n > 1)
Consider n = 2 here
if (n != 1)
{
if( n % 2 == 0) // Yes
n = (n - 1); // n = 1
return(findSumofOdds(n-1) + 1); // n = 0 <-- will not stop.
and change this too. right now it is just counting the number of odd numbers. You need to sum them.
return(n + findSumofOdds(n - 1));
}
else
return 0;
If you print n in findSumofOdds you can see what is happening -- n becomes negative and you get infinite recursion. If your program doesn't crash earlier, you can get integer overflow (when n goes below the minimum value for int) which yields undefined behavior.
To correct this you can do this:
int findSumofOdds(int n)
{
if(n < 1)
{
return 0;
}
if(n % 2 == 0)
{
return findSumofOdds(n - 1) + 1;
}
return findSumofOdds(n - 2) + 1;
}
You can subtract 2 from n in the last statement, because you only need odd numbers and you know that n can't be even at that point (because of if(n % 2 == 0)).
Also, do you need to find the sum of all odd numbers smaller than n (e.g. 4 (== 1 + 3) for n=5) or do you just need to count them (which is what you are doing now)?
If you want to sum the numbers, you have do add n instead of 1 when returning.