find LCM of two numbers in cpp - c++

/Here i wrote code for find LCM of two numbers but i don't know why it is not work for 9-10 digit numbers. like if i give input as 245 and 922222222 then it is not work and don't show the output./
//code is given below
#include<iostream>
using namespace std;
long long product;
long long lcm(long long x,long long y){
if(x>y)
product=x;
else
product=y;
while(1){
if(product%x==0 && product%y==0){
break;
}
product++;
}
return product;
}
int main(){
cout<<lcm(245,922222222);
return 0;
}

Your code is working fine, it's just going to take a few years for it to finish.
You're wasting a lot of time checking numbers that can't possibly be the result. n % (n + 1) can't possibly be 0 for any n other than 1. In general, n % (n + m) can only be 0 if m is a multiple of n. That means you can add the greater of x and y to product each loop instead of just 1 and cut down on a ton of work:
long long lcm(long long x,long long y) {
long long greater = std::max(x, y);
long long product = greater;
while(product % x != 0 || product % y != 0) {
product += greater;
}
return product;
}
Demo
Of course, even that is more work than you need, since std::gcd exists:
long long lcm(long long x, long long y) {
return x / std::gcd(x, y) * y;
}
Demo
That may be violating the spirit of the assignment though.

Related

Why would you ever add 10^9+7 to a number and then take mod with 10^9+7

I was solving a problem of Fenwick tree named shill and wave sequence and it wasn't passing all the test cases until I added a line looking at the solution and now want to find its purpose ,here is my code
#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
long long query(long long index,int p,long long **bit)
{
long long count=0;
for(;index>0;index-=(index&(-index)))
{
count=(count+bit[index][p])%mod;
}
return count;
}
void update(long long **bit,long long index,int p,long long val)
{
for(;index<=100000;index+=(index&(-index)))
{
bit[index][p]=(bit[index][p]+val)%mod;
}
}
int main()
{
int n;
cin>>n;
long long ans=0;
long long **bit=new long long*[100000+1];
for(int i=1;i<=100000;i++)
{
bit[i]=new long long[3];
for(int j=0;j<3;j++)
{
bit[i][j]=0;
}
}
for(int i=0;i<n;i++)
{
long long x;
cin>>x;
long long a=(query(x-1,0,bit)+query(x-1,2,bit))%mod;
long long b=(query(100000,1,bit)+query(100000,2,bit))%mod-query(x,1,bit)-query(x,2,bit);
b=(b+mod)%mod;
//WHAT IS THE PURPOSE OF ABOVE LINE?
ans+=(a+b)%mod;
update(bit,x,0,b);
update(bit,x,1,a);
update(bit,x,2,1);
}
cout<<ans%mod;
return 0;
}
b=(b+mod)%mod
but why?
For some cases b can be negative and may cause incorrect results while doing % directly. That's why before doing % operation it's safe to add mod and then do % which will make the number positive first and then do the modulo.
The "purpose" of the line (or rather, the reason that it has any effect) could be that
b=(b+mod)%mod;
changes the value of b.
So the remaning question is, does it matter that you add "mod" before applying %mod?
Mathematically speaking
(x+y) mod y = x mod y
However, in many programming languages, there is a maximum value of int and if you add up something too big, you get an integer overflow.
In that case, it can easily happen that
(x+y) mod y != x mod y
which could be the case for you.

miller-rabin test don't work for 252097800623

I'm trying to write miller-rabin test. I found few codes such as:
https://www.sanfoundry.com/cpp-program-implement-miller-rabin-primality-test/
https://www.geeksforgeeks.org/primality-test-set-3-miller-rabin/
Of course all this codes works for 252097800623 ( which is prime number ), but this is becaouse they are parsing it to int. When I changed all ints to long long in this codes they are now returning NO. I also wrote my own code based on another article and it worked when I was testing it with small numbers like 11, 101, 17 and even 1000000007, but chrashed on greater numbers like 252097800623. I want to write program that works for all integers from 1 to 10^18
EDIT
here is modified code form 1st link:
/*
* C++ Program to Implement Milong longer Rabin Primality Test
*/
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
/*
* calculates (a * b) % c taking long longo account that a * b might overflow
*/
long long mulmod(long long a, long long b, long long mod)
{
long long 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
*/
long long modulo(long long base, long long exponent, long long mod)
{
long long x = 1;
long long y = base;
while (exponent > 0)
{
if (exponent % 2 == 1)
x = (x * y) % mod;
y = (y * y) % mod;
exponent = exponent / 2;
}
return x % mod;
}
/*
* Milong longer-Rabin primality test, iteration signifies the accuracy
*/
bool Miller(long long p,long long iteration)
{
if (p < 2)
{
return false;
}
if (p != 2 && p % 2==0)
{
return false;
}
long long s = p - 1;
while (s % 2 == 0)
{
s /= 2;
}
for (long long i = 0; i < iteration; i++)
{
long long a = rand() % (p - 1) + 1, temp = s;
long long 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()
{
long long iteration = 5;
long long num;
cout<<"Enter long longeger to test primality: ";
cin>>num;
if (Miller(num, iteration))
cout<<num<<" is prime"<<endl;
else
cout<<num<<" is not prime"<<endl;
return 0;
}
The code in the first link, which you replicated in your question, replacing the (bad) macro ll with long long (although this produces exactly the same preprocessed code) and all int with long long, is already broken for large values, see compiler explorer here. I forced the compiler to evaluate the Miller function for 252097800623 at compile time, replacing the call to rand() with one random number 123456.
As you can see the compiler is telling me that it cannot do so, because there are integer overflows in the program. In particular:
<source>:133:17: error: static_assert expression is not an integral constant expression
static_assert(Miller(num, iteration));
^~~~~~~~~~~~~~~~~~~~~~
<source>:62:12: note: value 232307310937188460801 is outside the range of representable values of type 'long long'
y = (y * y) % mod;
^
<source>:104:14: note: in call to 'modulo(123457, 63024450155, 252097800623)'
ll mod = modulo(a, temp, p);
^
<source>:133:17: note: in call to 'Miller(252097800623, 5)'
static_assert(Miller(num, iteration));
As you can see long long is simply too small to handle inputs that large to this algorithm.

Number of Ways of selecting a city/cities from a list of N cities

There is a list of N cities numbered from 1 to N.
The task is to select the number of ways the city/cities can be chosen from the list.
At least 1 city has to be selected. As the answer can be large, print the answer modulo 10^9+7
Examples
Input Output
2 (test cases)
2 3
1 1
For test case 1: The only ways to select the cities is 1, 2 ,1 2
Therefore the answer is 3.
For test case 2: The only way to select a city is 1 Therefore the
answer is 1.
I tried in the following way (C language):
#include<stdio.h>
#include<math.h>
const long int REM = 1000000000+7;
int main()
{
int t; scanf("%d",&t); while(t--) {
long long int n; scanf("%lld",&n);
long long int res=1;
for(long long int i=0;i<n;i++) {
res<<=1;
res%=(REM);
}
printf("%lld\n",res-1);
}
return 0;
}
This is giving me Time Limit Exceeded. Please suggest me a better performance algorithm.
Thank You
The answer is number of all possible subsets (except the empty set) which 2^n - 1.
As 2^n will be very large and that's why the problem asks to do modular operation, you have to perform Modular Exponentiation to calculate 2^n.
#include<stdio.h>
#include<math.h>
#define MOD 1000000007
// calculate (b^e) % MOD
long long powerMod(long long b, long long e)
{
long long ret = 1;
b %= MOD;
while(e > 0)
{
if(e & 1) {
ret = (ret * b) % MOD;
}
b = (b * b) % MOD;
e >>= 1;
}
return ret % MOD;
}
int main()
{
long long tcase, n;
scanf("%lld",&tcase);
while(tcase--)
{
scanf("%lld", &n);
long long result = powerMod(2, n) - 1;
printf("%lld\n", result);
}
return 0;
}
You can use the binary exponentiation algorithm to solve each test case in logarithmic time.

fibonacci number generation trouble

I have to generate the n-th fibonacci number from the first (zero-th) number being a and second being b. Below is my code for calculating this. I have been using matrix exponentiation method:
But the solution is wrong.
costum input:509618737 460201239 229176339(in order a,b,n)a=zeroth value,b=first value,n=Nth value to be found.
output:995159166
correct output:945141656
What is the problem with my code?
#include<iostream>
using namespace std;
void multiply(long long F[2][2], long long M[2][2]);//prototype of function multiplying 2 matrices.
void power(long long F[2][2],long long n);//prototype for incresing power
long long fib(long long n,long long a,long long b)//function that returns result as answer modulo 10^9+7(since answer is too long).
{
long long F[2][2] = {{1,1},{1,0}};
if (n == 0)
return a;
else if(n==1)
return b;
else if(n>1)
power(F, n-1);
return (F[0][0]*a+F[0][1]*b)%1000000007;//here's where i am confused ,whether i should multyply a first or b first i.e.f[0][0]*a+f[0][1]*b or f[0][0]*b+f[0][1]*a.plz explain this point too.
}
void power(long long F[2][2], long long n)
{
if( n == 0 || n == 1)
return;
long long M[2][2] = {{1,1},{1,0}};
power(F, n/2);
multiply(F, F);
if (n%2 != 0)
multiply(F, M);
}
void multiply(long long F[2][2], long long M[2][2])//matrices multiplied.
{
long long x = F[0][0]*M[0][0] + F[0][1]*M[1][0];
long long y = F[0][0]*M[0][1] + F[0][1]*M[1][1];
long long z = F[1][0]*M[0][0] + F[1][1]*M[1][0];
long long w = F[1][0]*M[0][1] + F[1][1]*M[1][1];
F[0][0] = x;
F[0][1] = y;
F[1][0] = z;
F[1][1] = w;
}
int main()
{
long long t, a, b, n, ans;
cin>>t;//# of test cases
while(t--)
{
cin>>a;//zeroth value
cin>>b;//first value
cin>>n;//Nth fibonaaci no. to be generated
ans=fib(n,a,b);//value of Nth no.
cout<<ans<<"\n";
}
return 0;
}

C++ function to preform division

Im trying to make a function that does division with out the / symbol
long q(int nm1, int nm2)
{
long q = 0;
while ( num1 > num2)
{
some subtraction here
}
return q;
}
the idea is to assume the input is in order and the first is to be divided by the second.
This means subtract the second from the first until the second is less then the first number.
I tried many different ways to do this but for what ever reason I cant hit it.
For now I am assuming the number is positive and wont return division by zero (I can fix that later by calling my other functions)
This means subtract the the second from the first until the second is less than the first number.
And what's the problem with that?
int div(int num, int den)
{
int frac;
for (frac = 0; num >= den; num -= den, frac++)
;
return frac;
}
What you're original post is trying to do is the Division by repeated subtraction algorithm. Have a look at Wikipedia:
The simplest division algorithm, historically incorporated into a
greatest common divisor algorithm presented in Euclid's Elements, Book
VII, Proposition 1, finds the remainder given two positive integers
using only subtractions and comparisons
while N ≥ D do
N := N - D
end
return N
Just add a counter in your while loop to keep track of the number of iterations (which is what you will want to return) and after your loop N will contain your remainder (if it is not 0 of course).
This code will work only if the num and den are integer values.
int main( int num, int den )
{
if(den==0)
{
return 1;
}
else
{
while(num!=0)
{
num = num - den;
}
}
return 0;
}
Just improving the above answer slightly.
Use modulus
long div(int num, int den)
{
int frac;
int num2 = num;
for (frac = 0; num2 >= den; num2 -= den, frac++)
;
// i needed the original num and den.
return ( (long) frac )+( num % den );
// casts frac to long then adds the modulus remainder of the values.
}
just a bit optimization: you don't want to have linear time complexity with the input value
int div(int num, int den)
{
int result = 0;
int i;
long long x;
long long y;
if (num < 0) return -div(-num, den);
if (den < 0) return -div(num, den);
if (num < den) return 0;
x = num;
y = den;
i = 0;
while((i < 32) && (x > (y << (i+1)))) i++;
for(;i>0; i++)
{
if (x > (y << i))
{
x -= y;
result += 1 << i;
}
}
return result;
}