Skip to content

Commit 1ba20b6

Browse files
committed
Add solution
1 parent 56b5926 commit 1ba20b6

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// 2438. Range Product Queries of Powers
2+
// Given a positive integer n, there exists a 0-indexed array called powers, composed of the minimum number of powers of 2 that sum to n. The array is sorted in non-decreasing order, and there is only one way to form the array.
3+
// You are also given a 0-indexed 2D integer array queries, where queries[i] = [lefti, righti]. Each queries[i] represents a query where you have to find the product of all powers[j] with lefti <= j <= righti.
4+
// Return an array answers, equal in length to queries, where answers[i] is the answer to the ith query. Since the answer to the ith query may be too large, each answers[i] should be returned modulo 10^9 + 7.
5+
6+
7+
// Solution: Bit Manipulation & Prefix Product
8+
9+
// The most compact representation of any number is the bit representation.
10+
// It can't get more compact than that, otherwise it will end up breaking up each bit into further halves.
11+
12+
// The bit representation is small (log(n)), so we can generate it before performing the queries.
13+
14+
// Precompute the prefix product of the powers, so that we can efficiently query.
15+
// To get the quotient of two larger numbers with modulo, use modular inverse.
16+
17+
// m = number of queries
18+
// Time Complexity: O(log(n) + m) 176ms
19+
// Space Complexity: O(log(n)) 89MB
20+
function productQueries(n, queries) {
21+
const powers = [];
22+
for (let i = 0; i < 30; i++) {
23+
if ((1 << i) & n) {
24+
powers.push(BigInt(2 ** i));
25+
}
26+
}
27+
const prefixProduct = [1n, ...powers], MOD = 1000000007n;
28+
for (let i = 2; i < prefixProduct.length; i++) {
29+
prefixProduct[i] = (prefixProduct[i] * prefixProduct[i - 1]) % MOD;
30+
}
31+
const ans = [];
32+
for (let [left, right] of queries) {
33+
const product = (prefixProduct[right + 1] * modPow(prefixProduct[left], MOD - 2n, MOD)) % MOD;
34+
ans.push(Number(product));
35+
}
36+
return ans;
37+
};
38+
39+
function modPow(x, y, mod) {
40+
y = Number(y);
41+
let currPow = x, ans = 1n;
42+
while (y > 0) {
43+
if (y & 1) {
44+
ans = (ans * currPow) % mod;
45+
}
46+
currPow = (currPow * currPow) % mod;
47+
y >>= 1;
48+
}
49+
return ans;
50+
}
51+
52+
// Two test cases
53+
console.log(productQueries(15, [[0,1],[2,2],[0,3]])) // [2,4,64]
54+
console.log(productQueries(2, [[0,0]])) // [2]

0 commit comments

Comments
 (0)