Algorithm of calculate modulo after power - c++

Below a piece of code to calculate the value of a^b%c,
int powermod(int a,int b,int c)
{
int ans = 1;
while(b)
{
if(b&1)
ans=(ans*a)%c;
a=(a*a)%c;
b=b>>1;
}
return ans;
}
I tried to understand the algorithm behind the code but couldn't make it.
Can someone help to explain this to me? How this works and does the algorithm behind it have a name?

It's easier to see what's going on without the "modulo c" part:
int power(int a,int b)
{
int ans = 1;
while(b)
{
if(b&1)
ans *= a;
a=a*a;
b=b>>1;
}
return ans;
}
This is a standard algorithm to compute ab by considering b one bit at a time, starting with the least significant bit. For each bit of b, if it is 1, multiply the answer by the current value of a. Then, to move to the next bit, square a and shift b to the right by 1 bit. The theory of this algorithm is that x2m + 2n = x2mx2n.
This type of algorithm is known as "exponentiation by squaring", "square-and-multiply" or "binary exponentiation".
The posted algorithm (after correction as noted in the comments) does the same thing modulo c, using the fact that (x*y)%z == ((x%z) * (y%z)) % z (that is, the modulo operation can be applied either before or multiplication). It uses this to keep a less than c despite repeated squaring.

It use the binary thinking.
ab = ab1 ab2 ... abn when b1+...+bn=b
write b in binary, you will get ab0 a2*b1 a4*b2 ... a2nbn ,bi means the ith bit in binary b. It can only be 0 or 1.
Now we find out that we don't need to calculate a2n every time, as we can get it from a2n-1
Because of (ab)%c=(a%c)(b%c)%c, this algorithm do the mod operation when multiply.

Related

Problem with numbers and power of numbers

Problem:
In a given range (a, b) ( a <= b, 2 <= a, b <= 1000000 ) find all natural numbers that can be expressed in format x ^ n ( x and n are natural numbers ). If there are more than one possibility to present expressed number, present it with a bigger exponential value.
U1.txt
Screen
40 110
49 = 7^2; 64 = 2^6; 81 = 3^4; 100 = 10^2;
#include <iostream>
#include <fstream>
#include <cmath>
int Power(int number, int base);
int main()
{
int a, b;
std::ifstream fin("U1.txt");
fin >> a >> b;
fin.close();
for (int i = a; i <= b; i++)
{
int max_power = 0;
int min_base = 10;
bool found = false;
for (int j = 2; j <= 10; j++)
{
int power = Power(i, j);
if (power > 0)
{
if (max_power < power) { max_power = power; }
if (min_base > j) { min_base = j; }
found = true;
}
}
if (found)
{
std::cout << i << " = " << min_base << " ^ " << max_power << "; ";
}
}
return 0;
}
int Power(int number, int base)
{
int power = (log(number) / log(base) + 0.5);
if (pow(base, power) == number)
{
return power;
}
return 0;
}
I solved the problem. However, I don't understand few things:
How the int Power(int number, int base) function works. Why the log function is used? Why after division of two log functions the 0.5 is added? I found the Idea on the Internet.
I am not sure if this solution works on all cases. I didn't know what could be the biggest value of the base number so my for (int j = 2; j <= 10; j++) loop is going from 2 to 10. If there is a number that base is bigger the solution won't work.
Are there any easier ways to solve this problem?
How does the function work?
That's something the OP should have asked to the authors of that snippet (assuming it was copied verbatim or close).
The intent seems to check if a whole number power exists, such that in combination with the integral arguments number and base the following equation is satisfied:
number = base power
The function returns it or 0 if it doesn't exist, meaning that number is not an integral power of some integral base. To do so,
it uses a property of the logarithms:
n = bp
log(n) = p log(b)
p = log(n) / log(b)
it rounds the number[1] to the "closest" integer, to avoid cases where the limited precision of floating-point types and operations would have yield incorrect results in case of a simple truncation.
In the comments I've already made the example of std::log(1000)/std::log(10), which may produce a double result close to 3.0, but less than 3.0 (something like 2.9999999999999996). When stored in an int it would be truncated to 2.
It checks if the number found is the exact power which solve the previous equation, but that comparison has the same problems I mentioned before.
pow(base, power) == number // It compares a double with an int
Just like std::log, std::pow returns a double value, making all the calculations performed with those functions prone to subtle numerical errors (either by rounding or by accumulation when multiple operations are involved). It's often preferable to use integral types and operations, if possible, when accuracy (or absolute exactness[2]) is needed.
Is the algorithm correct?
I didn't know what could be the biggest value of the base number so my for loop is going from 2 to 10
That's just wrong. One of the constraints of the problem is b <= 1'000'000, but the posted solution couldn't find any power greater than 102.
An extimate of the greatest possible base is the square root of said b.
Are there any easier ways to solve this problem?
Easiness is subjective and we don't know all the requirements and constraints of OP's assignment. I'll describe an alternative solution without posting the code I wrote to test it[3].
OP's code considers all the numbers between a and b checking for every (well, up to 10) base if there exists a whole power.
My proposal uses only integral variables, of a wide enough type, say long (any 32-bit integer is enough).
The outer loop starts from base = 2 and increments it by one at every step.
Inside this loop, exponent is set to 2 and value to base * base
If value is greater than b, the algorithm stops.
While value is less than a, updates it (multiplying it by base) and the exponent (it's incremented by one). We need to find the first power of base which is greater or equal to a.
While value is less than or equal to b, store the triplet of variables value, base and exponent in suitable container.
Consider a std::map<long, std::pair<long, long>>, it lets us associate all the values with the corresponding pair of base and exponent. Also, it could be later traversed to obtain all the values in ascending order.
The assignment requires, in case of multiple powers, to present only the one with the bigger exponent. In the example, it shows 64 = 26, ignoring 64 = 43. Note the needed one is the one with the smaller base, so that it's enough to ignore any further value if it's already present in the map.
value and exponent are updated as before.
Note that this algorithm only consider bases up to the square root of b (in the outer loop) and the number of iterations of the inner loop is much more limited (with base = 2, it would be less than 20, beeing 220 > 1'000'000. Greater bases would stop sooner and sooner).
[1] See e.g. Why do lots of (old) programs use floor(0.5 + input) instead of round(input)?
[2] See e.g. The most efficient way to implement an integer based power function pow(int, int)
[3] How do I ask and answer homework questions?

How to get rid of 2 numbers' common divisors

So I have a function that divides a pair of numbers until they no longer have any common divisors:
void simplify(int &x, int &y){
for (int i = 2;;++i){
if (x < i && y < i){
return;
}
while (1){
if (!(x % i) && !(y % i)){
x /= i;
y /= i;
} else {
break;
}
}
}
}
How can I make it more efficient? I know one problem in this solution is that it tests for divisibility with compound numbers, when it wouldn't have any of it's factors by the time it gets to them, so it's just wasted calculations. Can I do this without the program knowing a set of primes beforehand/compute them during the function's runtime?
Use the Euclidean algorithm1:
Let a be the larger of two given positive integers and b be the smaller.
Let r be the remainder of a divided by b.
If r is zero, we are done, and b is the greatest common divisor.
Otherwise, let a take the value of b, let b take the value of r, and go to step 2.
Once you have the greatest common divisor, you can divide the original two numbers by it, which will yield two numbers with the same ratio but without any common factors greater than one.
Citation
1 Euclid, Elements, book VII, propositions 1 and 2, circa 300 BCE.
Notes
Euclid used subtraction, which has been changed here to remainder.
Once this algorithm is working, you might consider the slightly more intricate Binary GCD, which replaces division (which is slow on some processors) with subtraction and bit operations.
Sounds like a job for the C++17 library feature gcd.
#include <numeric>
void simplify(int &x, int &y)
{
const auto d = std::gcd(x, y);
x /= d;
y /= d;
}
Compiler Explorer

Convert a given integer to another in minimum steps

Given two numbers A and B of equal number of digits. Find the minimum number of steps to convert A to B by increasing or decreasing a single digit in A in every step.
For example: If A = 133 and B = 343, a possible solution is 133 -> 233 -> 333 -> 343. Minimum number of steps required is 3.
I tried a brute force approach. Here is my pseudo code
while(a!=b)
{
if(a<b)
{
find (b-a)
count number of digits in (b-a) keep it as n
add the power(10,n) to a
moves++;
}
else{
find (a-b)
count number of digits in (a-b) keep it as n
subtract the power(10,n) from a
moves++;
}
}
I was not able to get the correct answer on all test cases. Please suggest an efficient way to do this.
The solution to your problem would be
Traverse through a and b digit by digit, add the absolute value of the difference to a variable sum
sum would represent the number of digits needed to be changed
Time complexity O(number of digits)
function solve(a, b){
let sum = 0;
while(a>0 && b>0){
sum += Math.abs((a%10)-(b%10));
a = Math.floor(a/10);
b= Math.floor(b/10);
}
return sum;
}
console.log(solve(133, 343));
console.log(solve(1234, 1221));
Based on ideas from #K. Kirsz comment and #marvel308 answer, you can solve this problem via std::valarray, which is kind of an obscure standard container that does it's job here. You can run it here.
#include <iostream>
#include <valarray>
#include <string>
int solve(int a, int b)
{
std::valarray<char> va(std::to_string(a).data(), std::to_string(a).length());
std::valarray<char> vb(std::to_string(b).data(), std::to_string(b).length());
return (std::abs(va - vb)).sum();
}
int main()
{
int a, b;
std::cin >> a >> b;
std::cout << solve(a, b);
return 0;
}
Of course, the performance might drop here but if you want more readable code, this might be better.

How to calculate the sum of the bitwise xor values of all the distinct combination of the given numbers efficiently?

Given n(n<=1000000) positive integer numbers (each number is smaller than 1000000). The task is to calculate the sum of the bitwise xor ( ^ in c/c++) value of all the distinct combination of the given numbers.
Time limit is 1 second.
For example, if 3 integers are given as 7, 3 and 5, answer should be 7^3 + 7^5 + 3^5 = 12.
My approach is:
#include <bits/stdc++.h>
using namespace std;
int num[1000001];
int main()
{
int n, i, sum, j;
scanf("%d", &n);
sum=0;
for(i=0;i<n;i++)
scanf("%d", &num[i]);
for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
sum+=(num[i]^num[j]);
}
}
printf("%d\n", sum);
return 0;
}
But my code failed to run in 1 second. How can I write my code in a faster way, which can run in 1 second ?
Edit: Actually this is an Online Judge problem and I am getting Cpu Limit Exceeded with my above code.
You need to compute around 1e12 xors in order to brute force this. Modern processors can do around 1e10 such operations per second. So brute force cannot work; therefore they are looking for you to figure out a better algorithm.
So you need to find a way to determine the answer without computing all those xors.
Hint: can you think of a way to do it if all the input numbers were either zero or one (one bit)? And then extend it to numbers of two bits, three bits, and so on?
When optimising your code you can go 3 different routes:
Optimising the algorithm.
Optimising the calls to language and library functions.
Optimising for the particular architecture.
There may very well be a quicker mathematical way of xoring every pair combination and then summing them up, but I know it not. In any case, on the contemporary processors you'll be shaving off microseconds at best; that is because you are doing basic operations (xor and sum).
Optimising for the architecture also makes little sense. It normally becomes important in repetitive branching, you have nothing like that here.
The biggest problem in your algorithm is reading from the standard input. Despite the fact that "scanf" takes only 5 characters in your computer code, in machine language this is the bulk of your program. Unfortunately, if the data will actually change each time your run your code, there is no way around the requirement of reading from stdin, and there will be no difference whether you use scanf, std::cin >>, or even will attempt to implement your own method to read characters from input and convert them into ints.
All this assumes that you don't expect a human being to enter thousands of numbers in less than one second. I guess you can be running your code via: myprogram < data.
This function grows quadratically (thanks #rici). At around 25,000 positive integers with each being 999,999 (worst case) the for loop calculation alone can finish in approximately a second. Trying to make this work with input as you have specified and for 1 million positive integers just doesn't seem possible.
With the hint in Alan Stokes's answer, you may have a linear complexity instead of quadratic with the following:
std::size_t xor_sum(const std::vector<std::uint32_t>& v)
{
std::size_t res = 0;
for (std::size_t b = 0; b != 32; ++b) {
const std::size_t count_0 =
std::count_if(v.begin(), v.end(),
[b](std::uint32_t n) { return (n >> b) & 0x01; });
const std::size_t count_1 = v.size() - count_0;
res += count_0 * count_1 << b;
}
return res;
}
Live Demo.
Explanation:
x^y = Sum_b((x&b)^(y&b)) where b is a single bit mask (from 1<<0 to 1<<32).
For a given bit, with count_0 and count_1 the respective number of count of number with bit set to 0 or 1, we have count_0 * (count_0 - 1) 0^0, count_0 * count_1 0^1 and count_1 * (count_1 - 1) 1^1 (and 0^0 and 1^1 are 0).

Array Division - What is the best way to divide two numbers stored in an array?

I have two arrays (dividend, divisor):
dividend[] = {1,2,0,9,8,7,5,6,6};
divisor[] = {9,8};
I need the result (dividend/divisor) as:
quotient[] = {1,2,3,4,5,6,7};
I did this using array subtraction:
subtract divisor from dividend until dividend becomes 0 or less than divisor, each time incrementing quotient by 1,
but it takes a huge time. Is there a better way to do this?
Do long division.
Have a temporary storage of size equal to the divisor plus one, and initialized to zero:
accumulator[] = {0,0,0};
Now run a loop:
Shift each digit of the quotient one space to the left.
Shift each digit of the accumulator one space to the right.
Take the next digit of the dividend, starting from the most-significant end, and store it to the least-significant place of the accumulator.
Figure out accumulator / divisor and set the least-significant place of the quotient to the result. Set the accumulator to the remainder.
Used to use this same algorithm a lot in assembly language for CPUs what didn't have division instructions.
Other than that, have you considered using BigInt class (or the equivalent thing in your language) which will already does this for you?
You can use long division http://en.wikipedia.org/wiki/Long_division
Is there a better way to do this?
You can use long division.
You can use Long division algorithm or the more general Polynomial Long Division.
Why not convert them to integers and then use regular division?
in pseudocode:
int dividend_number
foreach i in dividend
dividend_number *= 10
dividend_number += i
int divisor_number
foreach i in divisor
divisor_number *= 10
divisor_number += i
int answer = dividend_number / divisor_number;
There you go!
A is the divident.
B is the divisor.
C is the integer quotinent
R is the rest.
Each "huge" number is a vector retaining a big number. In huge[0] we retain the number of digits the number has and thren the number is memorized backwards.
Let's say we had the number 1234, then the corespoding vector would be:
v[0]=4; //number of digits
v[1]=4;
v[2]=3;
v[3]=2;
v[4]=1;
....
SHL(H,1) does: H=H*10;
SGN(A,B) Compares the A and B numbers
SUBSTRACT(A,B) does: A=A-B;
DIVIDHUGE: makes the division using the mentioned procedures...
void Shl(Huge H, int Count)
/* H <- H*10ACount */
{
memmove(&H[Count+1],&H[1],sizeof(int)*H[0]);
memset(&H[1],0,sizeof(int)*Count);
H[0]+=Count;
}
int Sgn(Huge H1, Huge H2) {
while (H1[0] && !H1[H1[0]]) H1[0]--;
while (H2[0] && !H2[H2[0]]) H2[0]--;
if (H1[0] < H2[0]) {
return -1;
} else if (H1[0] > H2[0]) {
return +1;
}
for (int i = H1[0]; i > 0; --i) {
if (H1[i] < H2[i]) {
return -1;
} else if (H1[i] > H2[i]) {
return +1;
}
}
return 0;
}
void Subtract(Huge A, Huge B)
/* A <- A-B */
{ int i, T=0;
for (i=B[0]+1;i<=A[0];) B[i++]=0;
for (i=1;i<=A[0];i++)
A[i]+= (T=(A[i]-=B[i]+T)<0) ? 10 : 0;
while (!A[A[0]]) A[0]--;
}
void DivideHuge(Huge A, Huge B, Huge C, Huge R)
/* A/B = C rest R */
{ int i;
R[0]=0;C[0]=A[0];
for (i=A[0];i;i--)
{ Shl(R,1);R[1]=A[i];
C[i]=0;
while (Sgn(B,R)!=1)
{ C[i]++;
Subtract(R,B);
}
}
while (!C[C[0]] && C[0]>1) C[0]--;
}