Given three positive integers X, Y, Z. Find (X0+X1+X2+X3+X4+…………………..+Xy-1) % Z.
Examples:
Input: X = 4, Y = 5, Z = 6
Output: 5
Explanation: 40+41+42+43+44 = 1+4+16+64+256 = 341, 341%6 = 5, So 5 is the outputInput: X = 20000, Y = 35000, Z = 2555
Output: 791
Approach: This can be solved with the following idea:
- In this approach we have to calculate the value of the function f(y) = x1 * (x2 + 1) * (x4 + 1) * … * (x2^K+ 1) % z, where k is the largest power of 2 that is less than or equal to y.
- To solve this problem, we can use a greedy approach where we calculate the values of the function for each power of 2 less than or equal to x and then combine them to get the final answer. We can use a vector to store the values of the function and their corresponding powers of 2 and then iterate through this vector in reverse order to add up the terms that we need.
- We can also use the fast power algorithm to calculate the powers of a modulo m efficiently.
Proof of the approach:
To prove the correctness of this approach, we have to show that the function f(y) can be calculated by combining the values of the function for each power of 2 less than or equal to y.
- Let’s consider the value of the function f(y) for a given y. We can express y as a sum of powers of 2, where each power of 2 appears at most once. Let k be the largest power of 2 that is less than or equal to y. Then we have: y = 2k+r , where 0 ≤ r < 2k.
- Using this representation of y, we can express f(y) as: f(y) = x1 * (x2 + 1) * (x4 + 1) * … * (x2^k+1) * (x2^(k-1)+1)^(r/2k-1) * … * (x2^2+1)^(r/4) * (x2+1)^(r/2) * x1^(r), where r/2^i denotes the floor division of r by 2^i.
- Note that each term in this expression corresponds to a power of 2 less than or equal to y. The first k terms correspond to the powers of 2 up to 2^k, and the remaining terms correspond to the powers of 2 between 2^k and y.
- Using the fast power algorithm, we can efficiently compute each term in this expression. We can store the values of the function and their corresponding powers of 2 in a vector and iterate through this vector in reverse order to add up the terms that we need.
- Therefore, we have shown that the function f(y) can be calculated by combining the values of the function for each power of 2 less than or equal to y, using the approach described.
Below are the steps for the above approach:
- Initialize a vector of pairs of integers called v.
-
Loop through the powers of 2 less than or equal to y
- Append a new pair to v consisting of the value of the function for the current power of 2 and the power of 2 itself.
- Update the value of the function for the next power of 2 using the formula current = current * (pow (x, i, z) + 1) % z.
- Initialize integer variables ‘ans‘ and ‘res‘ to 0.
-
Loop through the pairs in ‘v‘ in reverse order:
- Remove the last pair from ‘v’ and assign it to ‘temp’.
- If y is less than temp.second, skip to the next iteration.
- Update ans = (ans + pow(x, res, z) * temp.first) % z.
- Update res = temp.second.
- Subtract the second element of ‘temp’ from y.
- Print the final value of ‘ans’.
Below is the implementation of the above code:
// C++ code of the above approach #include <bits/stdc++.h> #define int long long using namespace std;
// Define the power function with // parameters 'a', 'b', and 'm' int pow ( int a, int b, int m)
{ // If b is 0, return 1
if (!b)
return 1;
// Initialize a temporary variable
// to 1
int temp = 1;
// Loop through the binary digits of
// 'b' in reverse order
for ( int current = a; b;
b >>= 1, current = current * current % m)
// If the bit of 'b' is 1, multiply
// 'temp' by 'current' modulo 'm'
if (b & 1)
temp = temp * current % m;
return temp;
} void getValue( int x, int y, int z)
{ vector<pair< int , int > > v;
// Loop through the powers of 2 less
// than or equal to 'y'
for ( int i = 1, current = 1; i <= y; i <<= 1) {
// Append a new pair to 'v'
// consisting of 'current' and 'i'
v.push_back({ current, i });
// Update 'current' to be 'current'
// times 'x' to the power of 'i'
// modulo 'z' plus 1 modulo 'z'
current = current * ( pow (x, i, z) + 1) % z;
}
int ans = 0, res = 0;
// Loop through the pairs in 'v' in
// reverse order
while (v.size() > 0) {
// Remove the last pair from 'v'
// and assign it to 'temp'
pair< int , int > temp = v.back();
v.pop_back();
// If 'y' is less than the second
// element of 'temp', skip to the
// next iteration
if (y < temp.second)
continue ;
// Update 'ans' to be 'ans' plus
// 'x' to the power of 'res'
// modulo 'z' times the first
// element of 'tmp' modulo 'z'
ans = (ans + pow (x, res, z) * temp.first) % z;
// Update 'res' to be 'res' plus
// the second element of 'temp'
res += temp.second;
// Subtract the second element of
// 'temp' from 'y'
y -= temp.second;
}
cout << ans << endl;
} // Driver Code signed main()
{ int x = 20000, y = 35000, z = 2555;
// Function call
getValue(x, y, z);
return 0;
} |
// Java code implementation: import java.io.*;
import java.util.*;
// class pair class pair {
int first, second;
pair( int first, int second)
{
this .first = first;
this .second = second;
}
} class GFG {
// Define the power function with parameters 'a', 'b',
// and 'm'
static long pow( long a, long b, long m)
{
// If b is 0, return 1
if (b == 0 )
return 1 ;
// Initialize a temporary variable to 1
long temp = 1 ;
// Loop through the binary digits of 'b' in reverse
// order
for ( long current = a; b != 0 ;
b >>= 1 , current = current * current % m)
// If the bit of 'b' is 1, multiply 'temp' by
// 'current' modulo 'm'
if ((b & 1 ) == 1 )
temp = temp * current % m;
return temp;
}
static void getValue( int x, int y, int z)
{
List<pair> v = new ArrayList<pair>();
// Loop through the powers of 2 less than or equal
// to 'y'
for ( int i = 1 , current = 1 ; i <= y; i <<= 1 ) {
// Append a new pair to 'v' consisting of
// 'current' and 'i'
v.add( new pair(current, i));
// Update 'current' to be 'current' times 'x' to
// the power of 'i' modulo 'z' plus 1 modulo 'z'
current = ( int )(( long )current
* (pow(x, i, z) + 1 ) % z);
}
int ans = 0 , res = 0 ;
// Loop through the pairs in 'v' in reverse order
while (v.size() > 0 ) {
// Remove the last pair from 'v' and assign it
// to 'temp'
pair temp = v.get(v.size() - 1 );
v.remove(v.size() - 1 );
// If 'y' is less than the second element of
// 'temp', skip to the next iteration
if (y < temp.second)
continue ;
// Update 'ans' to be 'ans' plus 'x' to the
// power of 'res' modulo 'z' times the first
// element of 'tmp' modulo 'z'
ans = ( int )(( long )ans
+ pow(x, res, z) * temp.first % z)
% z;
// Update 'res' to be 'res' plus the second
// element of 'temp'
res += temp.second;
// Subtract the second element of 'temp' from
// 'y'
y -= temp.second;
}
System.out.println(ans);
}
public static void main(String[] args)
{
int x = 20000 , y = 35000 , z = 2555 ;
// Function call
getValue(x, y, z);
}
} // This code is contributed by sankar. |
# Define the power function with # parameters 'a', 'b', and 'm' def pow (a, b, m):
# If b is 0, return 1
if b = = 0 :
return 1
# Initialize a temporary variable
# to 1
temp = 1
# Loop through the binary digits of 'b' in reverse order
while b > 0 :
# If the bit of 'b' is 1, multiply 'temp' by 'a' modulo 'm'
if b & 1 :
temp = (temp * a) % m
# Update 'a' to be 'a' squared modulo 'm'
a = (a * a) % m
# Right shift 'b' by 1
b >> = 1
return temp
def getValue(x, y, z):
v = []
# Loop through the powers of 2 less than or equal to 'y'
current = 1
i = 1
while i < = y:
# Append a new pair to 'v' consisting of 'current' and 'i'
v.append((current, i))
# Update 'current' to be 'current' times 'x' to the
# power of 'i' modulo 'z' plus 1 modulo 'z'
current = (current * ( pow (x, i, z) + 1 )) % z
# Left shift 'i' by 1
i << = 1
ans = 0
res = 0
# Loop through the pairs in 'v' in reverse order
while v:
# Remove the last pair from 'v' and assign it to 'temp'
temp = v.pop()
# If 'y' is less than the second element of 'temp',
# skip to the next iteration
if y < temp[ 1 ]:
continue
# Update 'ans' to be 'ans' plus 'x' to the power of 'res'
# modulo 'z' times the first element of 'temp' modulo 'z'
ans = (ans + pow (x, res, z) * temp[ 0 ]) % z
# Update 'res' to be 'res' plus the second element of 'temp'
res + = temp[ 1 ]
# Subtract the second element of 'temp' from 'y'
y - = temp[ 1 ]
print (ans)
# Driver Code x = 20000
y = 35000
z = 2555
# Function call getValue(x, y, z) |
// C# code of the above approach using System;
using System.Collections.Generic;
class Pair
{ public int First { get ; set ; }
public int Second { get ; set ; }
public Pair( int first, int second)
{
First = first;
Second = second;
}
} class GFG
{ // Define the power function with parameters 'a', 'b',
// and 'm'
static long Pow( long a, long b, long m)
{
// If b is 0, return 1
if (b == 0)
return 1;
// Initialize a temporary variable to 1
long temp = 1;
// Loop through the binary digits of 'b' in reverse
// order
for ( long current = a; b != 0; b >>= 1, current = current * current % m)
{
if ((b & 1) == 1)
temp = temp * current % m;
}
return temp;
}
static void GetValue( int x, int y, int z)
{
List<Pair> v = new List<Pair>();
// Loop through the powers of 2 less than or equal
// to 'y'
for ( int i = 1, current = 1; i <= y; i <<= 1)
{
v.Add( new Pair(current, i));
current = ( int )(( long )current * (Pow(x, i, z) + 1) % z);
}
int ans = 0, res = 0;
while (v.Count > 0)
{
Pair temp = v[v.Count - 1];
v.RemoveAt(v.Count - 1);
if (y < temp.Second)
continue ;
// Update 'ans' to be 'ans' plus 'x' to the
// power of 'res' modulo 'z' times the first
// element of 'tmp' modulo 'z'
ans = ( int )(( long )ans + Pow(x, res, z) * temp.First % z) % z;
res += temp.Second;
y -= temp.Second;
}
Console.WriteLine(ans);
}
static void Main( string [] args)
{
int x = 20000, y = 35000, z = 2555;
// Function call
GetValue(x, y, z);
}
} // this code is contributed by codearcade |
// Javascript code of following approach // Define the power function with // parameters 'a', 'b', and 'm' function pow(a, b, m) {
// If b is 0, return 1
if (b === 0) {
return 1;
}
// Initialize a temporary variable
// to 1
let temp = 1;
// Loop through the binary digits of 'b' in reverse order
while (b > 0) {
// If the bit of 'b' is 1, multiply 'temp' by 'a' modulo 'm'
if (b & 1) {
temp = (temp * a) % m;
}
// Update 'a' to be 'a' squared modulo 'm'
a = (a * a) % m;
// Right shift 'b' by 1
b >>= 1;
}
return temp;
} function getValue(x, y, z) {
let v = [];
// Loop through the powers of 2 less than or equal to 'y'
let current = 1;
let i = 1;
while (i <= y) {
// Append a new pair to 'v' consisting of 'current' and 'i'
v.push([current, i]);
// Update 'current' to be 'current' times 'x' to the
// power of 'i' modulo 'z' plus 1 modulo 'z'
current = (current * (pow(x, i, z) + 1)) % z;
// Left shift 'i' by 1
i <<= 1;
}
let ans = 0;
let res = 0;
// Loop through the pairs in 'v' in reverse order
while (v.length > 0) {
// Remove the last pair from 'v' and assign it to 'temp'
let temp = v.pop();
// If 'y' is less than the second element of 'temp',
// skip to the next iteration
if (y < temp[1]) {
continue ;
}
// Update 'ans' to be 'ans' plus 'x' to the power of 'res'
// modulo 'z' times the first element of 'temp' modulo 'z'
ans = (ans + pow(x, res, z) * temp[0]) % z;
// Update 'res' to be 'res' plus the second element of 'temp'
res += temp[1];
// Subtract the second element of 'temp' from 'y'
y -= temp[1];
}
console.log(ans);
} // Driver Code let x = 20000; let y = 35000; let z = 2555; // Function call getValue(x, y, z); // This code is contributed by Dwaipayan Bandyopadhyay |
791
Time Complexity: O(log(y) * log(x))
Auxiliary Space: O(log y)