Given q queries, where each query is represented as queries[i] = [a, b], consisting of two positive integers a and b. For each query, find the least positive integer x such that (a*x - 1) is divisible by b. If no such integer exists for a given query, the answer for that query should be -1.
Return an array of integers, where the i-th element is the answer to the i-th query.
Examples :
Input: queries[][] = [[8, 10], [4, 9]]
Output: [-1, 7]
Explanation:
Query 1: a = 8, b = 10 -> There is no x such that 8x - 1 is divisible by 10.
Query 2: a = 4, b = 9 -> 7 is the least integer such that 4 * 7 - 1 = 27 is divisible by 9.
Input: queries[][] = [[3, 7], [6, 12], [5, 11]]
Output: [5, -1, 9]
Explanation:
Query 1: a = 3, b = 7 -> 3 * 5 - 1 = 14, divisible by 7.
Query 2: a = 6, b = 12 -> There is no x such that 6x - 1 is divisible by 12.
Query 3: a = 5, b = 11 -> 5 * 9 - 1 = 44, divisible by 11.
Table of Content
[Naive Approach] Try Every Possible Value of x One by One - O(q × b) Time and O(1) Space
The idea is to check every positive integer x from 1 to b. The first value for which (a * x - 1) is divisible by b is the required answer. If no such value exists, return -1.
#include <iostream>
#include <vector>
using namespace std;
vector<int> findXQueries(vector<vector<int>> &queries)
{
vector<int> ans;
// Process every query
for (auto &q : queries)
{
int a = q[0];
int b = q[1];
int res = -1;
// Try every possible value of x
for (int x = 1; x <= b; x++)
{
// Check if (a*x - 1) is divisible by b
if ((1LL * a * x - 1) % b == 0)
{
res = x;
break;
}
}
ans.push_back(res);
}
return ans;
}
int main()
{
vector<vector<int>> queries = {{3, 7}, {6, 12}, {5, 11}};
vector<int> ans = findXQueries(queries);
cout << "[";
for (int i = 0; i < ans.size(); i++)
{
cout << ans[i];
if (i != ans.size() - 1)
cout << ", ";
}
cout << "]";
return 0;
}
import java.util.ArrayList;
class GFG {
static ArrayList<Integer> findXQueries(int[][] queries)
{
ArrayList<Integer> ans = new ArrayList<>();
// Process every query
for (int[] q : queries) {
int a = q[0];
int b = q[1];
int res = -1;
// Try every possible value of x
for (int x = 1; x <= b; x++) {
// Check if (a*x - 1) is divisible by b
if (((long)a * x - 1) % b == 0) {
res = x;
break;
}
}
ans.add(res);
}
return ans;
}
public static void main(String[] args)
{
int[][] queries
= { { 3, 7 }, { 6, 12 }, { 5, 11 } };
ArrayList<Integer> ans = findXQueries(queries);
System.out.print("[");
for (int i = 0; i < ans.size(); i++) {
System.out.print(ans.get(i));
if (i != ans.size() - 1)
System.out.print(", ");
}
System.out.print("]");
}
}
def findXQueries(queries):
ans = []
# Process every query
for q in queries:
a = q[0]
b = q[1]
res = -1
# Try every possible value of x
for x in range(1, b + 1):
# Check if (a*x - 1) is divisible by b
if ((a * x - 1) % b == 0):
res = x
break
ans.append(res)
return ans
if __name__ == '__main__':
queries = [[3, 7], [6, 12], [5, 11]]
ans = findXQueries(queries)
print('[', end='')
for i in range(len(ans)):
print(ans[i], end='')
if i != len(ans) - 1:
print(', ', end='')
print(']')
using System;
using System.Collections.Generic;
class GFG {
static List<int> FindXQueries(int[, ] queries)
{
List<int> ans = new List<int>();
int q = queries.GetLength(0);
// Process every query
for (int i = 0; i < q; i++) {
int a = queries[i, 0];
int b = queries[i, 1];
int res = -1;
// Try every possible value of x
for (int x = 1; x <= b; x++) {
// Check if (a*x - 1) is divisible by b
if ((((long)a * x) - 1) % b == 0) {
res = x;
break;
}
}
ans.Add(res);
}
return ans;
}
static void Main()
{
int[, ] queries
= { { 3, 7 }, { 6, 12 }, { 5, 11 } };
List<int> ans = FindXQueries(queries);
Console.Write("[");
for (int i = 0; i < ans.Count; i++) {
Console.Write(ans[i]);
if (i != ans.Count - 1)
Console.Write(", ");
}
Console.Write("]");
}
}
function findXQueries(queries)
{
const ans = [];
// Process every query
for (const q of queries) {
const a = q[0];
const b = q[1];
let res = -1;
// Try every possible value of x
for (let x = 1; x <= b; x++) {
// Check if (a*x - 1) is divisible by b
if ((a * x - 1) % b === 0) {
res = x;
break;
}
}
ans.push(res);
}
return ans;
}
// Driver code
const queries = [ [ 3, 7 ], [ 6, 12 ], [ 5, 11 ] ];
const ans = findXQueries(queries);
console.log("[" + ans.join(", ") + "]");
Output
[5, -1, 9]
[Expected Approach] Using Modular Multiplicative Inverse - O(q × log(min(a, b))) Time and O(log(min(a, b))) Space
The idea is to convert the condition (a*x - 1) divisible by b into the modular equation a*x ≡ 1 (mod b). This means x is the modular inverse of a modulo b. The inverse exists only when gcd(a, b) = 1, and it can be found efficiently using the Extended Euclidean Algorithm.
Working of Approach:
- Convert the given condition (a × x - 1) divisible by b into the modular equation a × x ≡ 1 (mod b).
- A solution exists only when gcd(a, b) = 1; otherwise, the modular inverse does not exist, so return -1.
- Use the Extended Euclidean Algorithm to find integers x and y satisfying a × x + b × y = gcd(a, b).
- When the gcd is 1, the computed coefficient of a is its modular inverse. Normalize it to the range [1, b] to obtain the least positive answer.
- Repeat the same process independently for every query.
Let us understand with an example:
Input: queries[][] = [[3, 7], [6, 12], [5, 11]]
Query 1: a = 3, b = 7
- gcd(3, 7) = 1, so a modular inverse exists.
- Extended Euclid returns inverse 5.
- 3 × 5 - 1 = 14, which is divisible by 7.
- Answer = 5.
Query 2: a = 6, b = 12
- gcd(6, 12) = 6 ≠ 1.
- Modular inverse does not exist.
- Answer = -1.
Query 3: a = 5, b = 11
- gcd(5, 11) = 1, so a modular inverse exists.
- Extended Euclid returns inverse 9.
- 5 × 9 - 1 = 44, which is divisible by 11.
- Answer = 9.
Output: [5, -1, 9]
#include <vector>
#include <iostream>
using namespace std;
// Extended Euclidean Algorithm:
// returns {gcd, {x, y}} such that a*x + b*y = gcd(a, b)
pair<int, pair<int, int>> extendedEuclid(int a, int b)
{
// Base case: gcd(0, b) = b, via 0*0 + b*1 = b
if (a == 0)
return {b, {0, 1}};
auto p = extendedEuclid(b % a, a);
// Back-substitute: new x = y1 - (b/a)*x1, new y = x1
int x = p.second.second - p.second.first * (b / a);
int y = p.second.first;
return {p.first, {x, y}};
}
// Least positive x such that a*x - 1 is
// divisible by b (modular inverse of a mod b)
int findX(int a, int b)
{
auto p = extendedEuclid(a, b);
// Inverse exists only if gcd(a, b) = 1
if (p.first!= 1)
return -1;
int x = p.second.first;
// Normalize into [0, b); handles negative x
x = ((x % b) + b) % b;
// x=0 means b=1, so smallest positive solution is b itself
if (x == 0)
x = b;
return x;
}
// Answers each {a, b} query independently
// Time: O(q * log(min(a, b)))
vector<int> findXQueries(vector<vector<int>> &queries)
{
vector<int> res;
res.reserve(queries.size());
for (auto &q : queries)
{
res.push_back(findX(q[0], q[1]));
}
return res;
}
int main()
{
vector<vector<int>> queries = {{3, 7}, {6, 12}, {5, 11}};
vector<int> ans = findXQueries(queries);
cout << "[";
for (int i = 0; i < ans.size(); i++)
{
cout << ans[i];
if (i!= ans.size() - 1)
cout << ", ";
}
cout << "]";
return 0;
}
import java.util.ArrayList;
class GFG {
static class Triplet {
int gcd, x, y;
Triplet(int gcd, int x, int y)
{
this.gcd = gcd;
this.x = x;
this.y = y;
}
}
// Extended Euclidean Algorithm:
// returns {gcd, {x, y}} such that a*x + b*y = gcd(a, b)
static Triplet extendedEuclid(int a, int b)
{
// Base case: gcd(0, b) = b, via 0*0 + b*1 = b
if (a == 0)
return new Triplet(b, 0, 1);
Triplet p = extendedEuclid(b % a, a);
// Back-substitute: new x = y1 - (b/a)*x1, new y =
// x1
int x = p.y - p.x * (b / a);
int y = p.x;
return new Triplet(p.gcd, x, y);
}
// Least positive x such that a*x - 1 is divisible by b
// (modular inverse of a mod b)
static int findX(int a, int b)
{
Triplet p = extendedEuclid(a, b);
// Inverse exists only if gcd(a, b) = 1
if (p.gcd!= 1)
return -1;
int x = p.x;
// Normalize into [0, b); handles negative x
x = ((x % b) + b) % b;
// x=0 means b=1, so smallest positive solution is b
// itself
if (x == 0)
x = b;
return x;
}
// Answers each {a, b} query independently
// Time: O(q * log(min(a, b)))
static ArrayList<Integer> findXQueries(int[][] queries)
{
ArrayList<Integer> res = new ArrayList<>();
for (int[] q : queries)
res.add(findX(q[0], q[1]));
return res;
}
public static void main(String[] args)
{
int[][] queries
= { { 3, 7 }, { 6, 12 }, { 5, 11 } };
ArrayList<Integer> ans = findXQueries(queries);
System.out.print("[");
for (int i = 0; i < ans.size(); i++) {
System.out.print(ans.get(i));
if (i!= ans.size() - 1)
System.out.print(", ");
}
System.out.print("]");
}
}
# Extended Euclidean Algorithm:
# returns {gcd, {x, y}} such that a*x + b*y = gcd(a, b)
def extendedEuclid(a, b):
# Base case: gcd(0, b) = b, via 0*0 + b*1 = b
if a == 0:
return (b, (0, 1))
p = extendedEuclid(b % a, a)
# Back-substitute: new x = y1 - (b/a)*x1, new y = x1
x = p[1][1] - p[1][0] * (b // a)
y = p[1][0]
return (p[0], (x, y))
# Least positive x such that a*x - 1 is
# divisible by b (modular inverse of a mod b)
def findX(a, b):
p = extendedEuclid(a, b)
# Inverse exists only if gcd(a, b) = 1
if p[0] != 1:
return -1
x = p[1][0]
# Normalize into [0, b); handles negative x
x = ((x % b) + b) % b
# x=0 means b=1, so smallest positive solution is b itself
if x == 0:
x = b
return x
# Answers each {a, b} query independently
# Time: O(q * log(min(a, b)))
def findXQueries(queries):
res = []
for q in queries:
res.append(findX(q[0], q[1]))
return res
if __name__ == '__main__':
queries = [[3, 7], [6, 12], [5, 11]]
ans = findXQueries(queries)
print('[',end="")
for i in range(len(ans)):
print(ans[i], end='' if i == len(ans) - 1 else ', ')
print(']')
using System;
using System.Collections.Generic;
class GFG {
class Triplet {
public int gcd, x, y;
public Triplet(int gcd, int x, int y)
{
this.gcd = gcd;
this.x = x;
this.y = y;
}
}
// Extended Euclidean Algorithm:
// returns {gcd, {x, y}} such that a*x + b*y = gcd(a, b)
static Triplet ExtendedEuclid(int a, int b)
{
// Base case: gcd(0, b) = b, via 0*0 + b*1 = b
if (a == 0)
return new Triplet(b, 0, 1);
Triplet p = ExtendedEuclid(b % a, a);
// Back-substitute: new x = y1 - (b/a)*x1, new y =
// x1
int x = p.y - p.x * (b / a);
int y = p.x;
return new Triplet(p.gcd, x, y);
}
// Least positive x such that a*x - 1 is divisible by b
// (modular inverse of a mod b)
static int FindX(int a, int b)
{
Triplet p = ExtendedEuclid(a, b);
// Inverse exists only if gcd(a, b) = 1
if (p.gcd != 1)
return -1;
int x = p.x;
// Normalize into [0, b); handles negative x
x = ((x % b) + b) % b;
// x=0 means b=1, so smallest positive solution is b
// itself
if (x == 0)
x = b;
return x;
}
// Answers each {a, b} query independently
// Time: O(q * log(min(a, b)))
static List<int> findXQueries(int[, ] queries)
{
int q = queries.GetLength(0);
List<int> res = new List<int>(q);
for (int i = 0; i < q; i++)
res.Add(FindX(queries[i, 0], queries[i, 1]));
return res;
}
static void Main()
{
int[, ] queries
= { { 3, 7 }, { 6, 12 }, { 5, 11 } };
List<int> ans = findXQueries(queries);
Console.Write("[");
for (int i = 0; i < ans.Count; i++) {
Console.Write(ans[i]);
if (i != ans.Count - 1)
Console.Write(", ");
}
Console.Write("]");
}
}
// Extended Euclidean Algorithm:
// returns {gcd, {x, y}} such that a*x + b*y = gcd(a, b)
function extendedEuclid(a, b)
{
// Base case: gcd(0, b) = b, via 0*0 + b*1 = b
if (a === 0)
return {gcd : b, coeffs : [ 0, 1 ]};
const p = extendedEuclid(b % a, a);
// Back-substitute: new x = y1 - (b/a)*x1, new y = x1
const x = p.coeffs[1] - p.coeffs[0] * Math.floor(b / a);
const y = p.coeffs[0];
return {gcd : p.gcd, coeffs : [ x, y ]};
}
// Least positive x such that a*x - 1 is divisible by b
// (modular inverse of a mod b)
function findX(a, b)
{
const p = extendedEuclid(a, b);
// Inverse exists only if gcd(a, b) = 1
if (p.gcd !== 1)
return -1;
let x = p.coeffs[0];
// Normalize into [0, b); handles negative x
x = ((x % b) + b) % b;
// x=0 means b=1, so smallest positive solution is b
// itself
if (x === 0)
x = b;
return x;
}
// Answers each {a, b} query independently
// Time: O(q * log(min(a, b)))
function findXQueries(queries)
{
const res = [];
for (const q of queries) {
res.push(findX(q[0], q[1]));
}
return res;
}
// Driver code
const queries = [ [ 3, 7 ], [ 6, 12 ], [ 5, 11 ] ];
const ans = findXQueries(queries);
console.log("["+ans.join(", ")+"]");
Output
[5, -1, 9]