Given 3 numbers a b c get a^b , b^a , c^x where x is abs diff between b and a cout each one but mod 10^9+7 in ascending order.
well I searched web for how to use the distributive property but didn't understand it since I am beginner,
I use very simple for loops so understanding this problem is a bit hard for me so how can I relate these mod rules with powers too in loops? If anyone can help me I would be so happy.
note time limit is 1 second which makes it harder
I tried to mod the result every time in the loop then times it by the original number.
for example if 2^3 then 1st loop given variables cin>>a,a would be 2, num =a would be like this
a = (a % 10^9 + 7) * num this works for very small inputs but large ones it exceed time
#include <iostream>
#include <cmath>
using namespace std;
int main ()
{
long long a,b,c,one,two,thr;
long long x;
long long mod = 1e9+7;
cin>>a>>b>>c;
one = a;
two = b;
thr = c;
if (a>=b)
x = a - b;
else
x = b - a;
for(int i = 0; i < b-1;i++)
{
a = ((a % mod) * (one%mod))%mod;
}
for(int j = 0; j < a-1;j++)
{
b = ((b % mod) * (two%mod))%mod;
}
for(int k = 0; k < x-1;k++)
{
c = ((c % mod) * (thr%mod))%mod;
}
}
I use very simple for loops [...] this works for very small inputs, but large ones it exceeds time.
There is an algorithm called "exponentiation by squaring" that has a logarithmic time complexity, rather then a linear one.
It works breaking down the power exponent while increasing the base.
Consider, e.g. x355. Instead of multiplying x 354 times, we can observe that
x355 = x·x354 = x·(x2)177 = x·x2·(x2)176 = x·x2·(x4)88 = x·x2·(x8)44 = x·x2·(x16)22 = x·x2·(x32)11 = x·x2·x32·(x32)10 = x·x2·x32·(x64)5 = x·x2·x32·x64·(x64)4 = x·x2·x32·x64·(x128)2 = x1·x2·x32·x64·x256
That took "only" 12 steps.
To implement it, we only need to be able to perform modular multiplications safely, without overflowing. Given the value of the modulus, a type like std::int64_t is wide enough.
#include <iostream>
#include <cstdint>
#include <limits>
#include <cassert>
namespace modular
{
auto exponentiation(std::int64_t base, std::int64_t exponent) -> std::int64_t;
}
int main()
{
std::int64_t a, b, c;
std::cin >> a >> b >> c;
auto const x{ b < a ? a - b : b - a };
std::cout << modular::exponentiation(a, b) << '\n'
<< modular::exponentiation(b, a) << '\n'
<< modular::exponentiation(c, x) << '\n';
return 0;
}
namespace modular
{
constexpr std::int64_t M{ 1'000'000'007 };
// We need the mathematical modulo
auto from(std::int64_t x)
{
static_assert(M > 0);
x %= M;
return x < 0 ? x + M : x;
}
// It assumes that both a and b are already mod M
auto multiplication_(std::int64_t a, std::int64_t b)
{
assert( 0 <= a and a < M and 0 <= b and b < M );
assert( b == 0 or a <= std::numeric_limits<int64_t>::max() / b );
return (a * b) % M;
}
// Implements exponentiation by squaring
auto exponentiation(std::int64_t base, std::int64_t exponent) -> std::int64_t
{
assert( exponent >= 0 );
auto b{ from(base) };
std::int64_t x{ 1 };
while ( exponent > 1 )
{
if ( exponent % 2 != 0 )
{
x = multiplication_(x, b);
--exponent;
}
b = multiplication_(b, b);
exponent /= 2;
}
return multiplication_(b, x);
}
}
Given two integers X and Y, whats the most efficient way of converting them into X.Y float value in C++?
E.g.
X = 3, Y = 1415 -> 3.1415
X = 2, Y = 12 -> 2.12
Here are some cocktail-napkin benchmark results, on my machine, for all solutions converting two ints to a float, as of the time of writing.
Caveat: I've now added a solution of my own, which seems to do well, and am therefore biased! Please double-check my results.
Test
Iterations
ns / iteration
#aliberro's conversion v2
79,113,375
13
#3Dave's conversion
84,091,005
12
#einpoklum's conversion
1,966,008,981
0
#Ripi2's conversion
47,374,058
21
#TarekDakhran's conversion
1,960,763,847
0
CPU: Quad Core Intel Core i5-7600K speed/min/max: 4000/800/4200 MHz
Devuan GNU/Linux 3
Kernel: 5.2.0-3-amd64 x86_64
GCC 9.2.1, with flags: -O3 -march=native -mtune=native
Benchmark code (Github Gist).
float sum = x + y / pow(10,floor(log10(y)+1));
log10 returns log (base 10) of its argument. For 1234, that'll be 3 point something.
Breaking this down:
log10(1234) = 3.091315159697223
floor(log10(1234)+1) = 4
pow(10,4) = 10000.0
3 + 1234 / 10000.0 = 3.1234.
But, as #einpoklum pointed out, log(0) is NaN, so you have to check for that.
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
float foo(int x, unsigned int y)
{
if (0==y)
return x;
float den = pow(10,-1 * floor(log10(y)+1));
return x + y * den;
}
int main()
{
vector<vector<int>> tests
{
{3,1234},
{1,1000},
{2,12},
{0,0},
{9,1}
};
for(auto& test: tests)
{
cout << "Test: " << test[0] << "," << test[1] << ": " << foo(test[0],test[1]) << endl;
}
return 0;
}
See runnable version at:
https://onlinegdb.com/rkaYiDcPI
With test output:
Test: 3,1234: 3.1234
Test: 1,1000: 1.1
Test: 2,12: 2.12
Test: 0,0: 0
Test: 9,1: 9.1
Edit
Small modification to remove division operation.
(reworked solution)
Initially, my thoughts were improving on the performance of power-of-10 and division-by-power-of-10 by writing specialized versions of these functions, for integers. Then there was #TarekDakhran's comment about doing the same for counting the number of digits. And then I realized: That's essentially doing the same thing twice... so let's just integrate everything. This will, specifically, allow us to completely avoid any divisions or inversions at runtime:
inline float convert(int x, int y) {
float fy (y);
if (y == 0) { return float(x); }
if (y >= 1e9) { return float(x + fy * 1e-10f); }
if (y >= 1e8) { return float(x + fy * 1e-9f); }
if (y >= 1e7) { return float(x + fy * 1e-8f); }
if (y >= 1e6) { return float(x + fy * 1e-7f); }
if (y >= 1e5) { return float(x + fy * 1e-6f); }
if (y >= 1e4) { return float(x + fy * 1e-5f); }
if (y >= 1e3) { return float(x + fy * 1e-4f); }
if (y >= 1e2) { return float(x + fy * 1e-3f); }
if (y >= 1e1) { return float(x + fy * 1e-2f); }
return float(x + fy * 1e-1f);
}
Additional notes:
This will work for y == 0; but - not for negative x or y values. Adapting it for negative value is pretty easy and not very expensive though.
Not sure if this is absolutely optimal. Perhaps a binary-search for the number of digits of y would work better?
A loop would make the code look nicer; but the compiler would need to unroll it. Would it unroll the loop and compute all those floats beforehand? I'm not sure.
I put some effort into optimizing my previous answer and ended up with this.
inline uint32_t digits_10(uint32_t x) {
return 1u
+ (x >= 10u)
+ (x >= 100u)
+ (x >= 1000u)
+ (x >= 10000u)
+ (x >= 100000u)
+ (x >= 1000000u)
+ (x >= 10000000u)
+ (x >= 100000000u)
+ (x >= 1000000000u)
;
}
inline uint64_t pow_10(uint32_t exp) {
uint64_t res = 1;
while(exp--) {
res *= 10u;
}
return res;
}
inline double fast_zip(uint32_t x, uint32_t y) {
return x + static_cast<double>(y) / pow_10(digits_10(y));
}
double IntsToDbl(int ipart, int decpart)
{
//The decimal part:
double dp = (double) decpart;
while (dp > 1)
{
dp /= 10;
}
//Joint boths parts
return ipart + dp;
}
Simple and very fast solution is converting both values x and y to string, then concatenate them, then casting the result into a floating number as following:
#include <string>
#include <iostream>
std::string x_string = std::to_string(x);
std::string y_string = std::to_string(y);
std::cout << x_string +"."+ y_string ; // the result, cast it to float if needed
(Answer based on the fact that OP has not indicated what they want to use the float for.)
The fastest (most efficient) way is to do it implicitly, but not actually do anything (after compiler optimizations).
That is, write a "pseudo-float" class, whose members are integers of x and y's types before and after the decimal point; and have operators for doing whatever it is you were going to do with the float: operator+, operator*, operator/, operator- and maybe even implementations of pow(), log2(), log10() and so on.
Unless what you were planning to do is literally save a 4-byte float somewhere for later use, it would almost certainly be faster if you had the next operand you need to work with then to really create a float from just x and y, already losing precision and wasting time.
Try this
#include <iostream>
#include <math.h>
using namespace std;
float int2Float(int integer,int decimal)
{
float sign = integer/abs(integer);
float tm = abs(integer), tm2 = abs(decimal);
int base = decimal == 0 ? -1 : log10(decimal);
tm2/=pow(10,base+1);
return (tm+tm2)*sign;
}
int main()
{
int x,y;
cin >>x >>y;
cout << int2Float(x,y);
return 0;
}
version 2, try this out
#include <iostream>
#include <cmath>
using namespace std;
float getPlaces(int x)
{
unsigned char p=0;
while(x!=0)
{
x/=10;
p++;
}
float pow10[] = {1.0f,10.0f,100.0f,1000.0f,10000.0f,100000.0f};//don't need more
return pow10[p];
}
float int2Float(int x,int y)
{
if(y == 0) return x;
float sign = x != 0 ? x/abs(x) : 1;
float tm = abs(x), tm2 = abs(y);
tm2/=getPlaces(y);
return (tm+tm2)*sign;
}
int main()
{
int x,y;
cin >>x >>y;
cout << int2Float(x,y);
return 0;
}
If you want something that is simple to read and follow, you could try something like this:
float convertToDecimal(int x)
{
float y = (float) x;
while( y > 1 ){
y = y / 10;
}
return y;
}
float convertToDecimal(int x, int y)
{
return (float) x + convertToDecimal(y);
}
This simply reduces one integer to the first floating point less than 1 and adds it to the other one.
This does become a problem if you ever want to use a number like 1.0012 to be represented as 2 integers. But that isn't part of the question. To solve it, I would use a third integer representation to be the negative power of 10 for multiplying the second number. IE 1.0012 would be 1, 12, 4. This would then be coded as follows:
float convertToDecimal(int num, int e)
{
return ((float) num) / pow(10, e);
}
float convertToDecimal(int x, int y, int e)
{
return = (float) x + convertToDecimal(y, e);
}
It a little more concise with this answer, but it doesn't help to answer your question. It might help show a problem with using only 2 integers if you stick with that data model.
Is there a C++ algorithm to calculate the least common multiple for multiple numbers, like lcm(3,6,12) or lcm(5,7,9,12)?
You can use std::accumulate and some helper functions:
#include <iostream>
#include <numeric>
int gcd(int a, int b)
{
for (;;)
{
if (a == 0) return b;
b %= a;
if (b == 0) return a;
a %= b;
}
}
int lcm(int a, int b)
{
int temp = gcd(a, b);
return temp ? (a / temp * b) : 0;
}
int main()
{
int arr[] = { 5, 7, 9, 12 };
int result = std::accumulate(arr, arr + 4, 1, lcm);
std::cout << result << '\n';
}
boost provides functions for calculation lcm of 2 numbers (see here)
Then using the fact that
lcm(a,b,c) = lcm(lcm(a,b),c)
You can easily calculate lcm for multiple numbers as well
As of C++17, you can use std::lcm.
And here is a little program that shows how to specialize it for multiple parameters
#include <numeric>
#include <iostream>
namespace math {
template <typename M, typename N>
constexpr auto lcm(const M& m, const N& n) {
return std::lcm(m, n);
}
template <typename M, typename ...Rest>
constexpr auto lcm(const M& first, const Rest&... rest) {
return std::lcm(first, lcm(rest...));
}
}
auto main() -> int {
std::cout << math::lcm(3, 6, 12, 36) << std::endl;
return 0;
}
See it in action here: https://wandbox.org/permlink/25jVinGytpvPaS4v
The algorithm isn't specific to C++. AFAIK, there's no standard library function.
To calculate the LCM, you first calculate the GCD (Greatest Common Divisor) using Euclids algorithm.
http://en.wikipedia.org/wiki/Greatest_common_divisor
The GCD algorithm is normally given for two parameters, but...
GCD (a, b, c) = GCD (a, GCD (b, c))
= GCD (b, GCD (a, c))
= GCD (c, GCD (a, b))
= ...
To calculate the LCM, use...
a * b
LCM (a, b) = ----------
GCD (a, b)
The logic for that is based on prime factorization. The more general form (more than two variables) is...
a b
LCM (a, b, ...) = GCD (a, b, ...) * --------------- * --------------- * ...
GCD (a, b, ...) GCD (a, b, ...)
EDIT - actually, I think that last bit may be wrong. The first LCM (for two parameters) is right, though.
Using GCC with C++14 following code worked for me:
#include <algorithm>
#include <vector>
std::vector<int> v{4, 6, 10};
auto lcm = std::accumulate(v.begin(), v.end(), 1, [](auto & a, auto & b) {
return abs(a * b) / std::__gcd(a, b);
});
In C++17 there is std::lcm function (http://en.cppreference.com/w/cpp/numeric/lcm) that could be used in accumulate directly.
Not built in to the standard library. You need to either build it yourself or get a library that did it. I bet Boost has one...
I just created gcd for multiple numbers:
#include <iostream>
using namespace std;
int dbd(int n, int k, int y = 0);
int main()
{
int h = 0, n, s;
cin >> n;
s = dbd(n, h);
cout << s;
}
int dbd(int n, int k, int y){
int d, x, h;
cin >> x;
while(x != y){
if(y == 0){
break;
}
if( x > y){
x = x - y;
}else{
y = y - x;
}
}
d = x;
k++;
if(k != n){
d = dbd(n, k, x);
}
return d;
}
dbd - gcd.
n - number of numbers.
/*
Copyright (c) 2011, Louis-Philippe Lessard
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
unsigned gcd ( unsigned a, unsigned b );
unsigned gcd_arr(unsigned * n, unsigned size);
unsigned lcm(unsigned a, unsigned b);
unsigned lcm_arr(unsigned * n, unsigned size);
int main()
{
unsigned test1[] = {8, 9, 12, 13, 39, 7, 16, 24, 26, 15};
unsigned test2[] = {2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};
unsigned result;
result = gcd_arr(test1, sizeof(test1) / sizeof(test1[0]));
result = gcd_arr(test2, sizeof(test2) / sizeof(test2[0]));
result = lcm_arr(test1, sizeof(test1) / sizeof(test1[0]));
result = lcm_arr(test2, sizeof(test2) / sizeof(test2[0]));
return result;
}
/**
* Find the greatest common divisor of 2 numbers
* See http://en.wikipedia.org/wiki/Greatest_common_divisor
*
* #param[in] a First number
* #param[in] b Second number
* #return greatest common divisor
*/
unsigned gcd ( unsigned a, unsigned b )
{
unsigned c;
while ( a != 0 )
{
c = a;
a = b%a;
b = c;
}
return b;
}
/**
* Find the least common multiple of 2 numbers
* See http://en.wikipedia.org/wiki/Least_common_multiple
*
* #param[in] a First number
* #param[in] b Second number
* #return least common multiple
*/
unsigned lcm(unsigned a, unsigned b)
{
return (b / gcd(a, b) ) * a;
}
/**
* Find the greatest common divisor of an array of numbers
* See http://en.wikipedia.org/wiki/Greatest_common_divisor
*
* #param[in] n Pointer to an array of number
* #param[in] size Size of the array
* #return greatest common divisor
*/
unsigned gcd_arr(unsigned * n, unsigned size)
{
unsigned last_gcd, i;
if(size < 2) return 0;
last_gcd = gcd(n[0], n[1]);
for(i=2; i < size; i++)
{
last_gcd = gcd(last_gcd, n[i]);
}
return last_gcd;
}
/**
* Find the least common multiple of an array of numbers
* See http://en.wikipedia.org/wiki/Least_common_multiple
*
* #param[in] n Pointer to an array of number
* #param[in] size Size of the array
* #return least common multiple
*/
unsigned lcm_arr(unsigned * n, unsigned size)
{
unsigned last_lcm, i;
if(size < 2) return 0;
last_lcm = lcm(n[0], n[1]);
for(i=2; i < size; i++)
{
last_lcm = lcm(last_lcm, n[i]);
}
return last_lcm;
}
Source code reference
You can calculate LCM and or GCM in boost like this:
#include <boost/math/common_factor.hpp>
#include <algorithm>
#include <iterator>
int main()
{
using std::cout;
using std::endl;
cout << "The GCD and LCM of 6 and 15 are "
<< boost::math::gcd(6, 15) << " and "
<< boost::math::lcm(6, 15) << ", respectively."
<< endl;
cout << "The GCD and LCM of 8 and 9 are "
<< boost::math::static_gcd<8, 9>::value
<< " and "
<< boost::math::static_lcm<8, 9>::value
<< ", respectively." << endl;
}
(Example taken from http://www.boost.org/doc/libs/1_31_0/libs/math/doc/common_factor.html)
The Codes given above only discusses about evaluating LCM for multiple numbers however it is very likely to happen that while performing multiplications we may overflow integer limit for data type storage
*A Corner Case :- *
e.g.
if while evaluating you reach situation such that if LCM_till_now=1000000000000000 next_number_in_list=99999999999999 and Hence GCD=1 (as both of them are relatively co-prime to each other)
So if u perform operation (LCM_till_now*next_number_in_list) will not even fit in "unsigned long long int"
Remedy :-
1.Use Big Integer Class
2.Or if the problem is asking for LCM%MOD----------->then apply properties of modular arithmetic.
Using the fact that lcm should be divisible
by all the numbers in list. Here the list is a vector containing numbers
int lcm=*(len.begin());
int ini=lcm;
int val;
int i=1;
for(it=len.begin()+1;it!=len.end();it++)
{
val=*it;
while(lcm%(val)!=0)
{
lcm+=ini;
}
ini=lcm;
}
printf("%llu\n",lcm);
len.clear();
I found this while searching a similar problem and wanted to contribute what I came up with for two numbers.
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
cin >> x >> y;
// zero is not a common multiple so error out
if (x * y == 0)
return -1;
int n = min(x, y);
while (max(x, y) % n)
n--;
cout << n << endl;
}
#include<iostream>
using namespace std;
int lcm(int, int, int);
int main()
{
int a, b, c, ans;
cout<<"Enter the numbers to find its LCM"<<endl; //NOTE: LCM can be found only for non zero numbers.
cout<<"A = "; cin>>a;
cout<<"B = "; cin>>b;
cout<<"C = "; cin>>c;
ans = lcm(a,b,c);
cout<<"LCM of A B and C is "<<ans;
}
int lcm(int a, int b, int c){
static int i=1;
if(i%a == 0 && i%b == 0 && i%c ==0){ //this can be altered according to the number of parameters required i.e this is for three inputs
return i;
} else {
i++;
lcm(a,b,c);
return i;
}
}
If you look at this page, you can see a fairly simple algorithm you could use. :-)
I'm not saying it's efficient or anything, mind, but it does conceptually scale to multiple numbers. You only need space for keeping track of your original numbers and a cloned set that you manipulate until you find the LCM.
#include
#include
void main()
{
clrscr();
int x,y,gcd=1;
cout<>x;
cout<>y;
for(int i=1;i<1000;++i)
{
if((x%i==0)&&(y%i==0))
gcd=i;
}
cout<<"\n\n\nGCD :"<
cout<<"\n\n\nLCM :"<<(x*y)/gcd;
getch();
}
let the set of numbers whose lcm you wish to calculate be theta
let i, the multiplier, be = 1
let x = the largest number in theta
x * i
if for every element j in theta, (x*i)%j=0 then x*i is the least LCM
if not, loop, and increment i by 1