Skip to content

Commit 6a5e066

Browse files
committed
Add solution #3539
1 parent 466db05 commit 6a5e066

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2772,6 +2772,7 @@
27722772
3516|[Find Closest Person](./solutions/3516-find-closest-person.js)|Easy|
27732773
3520|[Minimum Threshold for Inversion Pairs Count](./solutions/3520-minimum-threshold-for-inversion-pairs-count.js)|Medium|
27742774
3535|[Unit Conversion II](./solutions/3535-unit-conversion-ii.js)|Medium|
2775+
3539|[Find Sum of Array Product of Magical Sequences](./solutions/3539-find-sum-of-array-product-of-magical-sequences.js)|Hard|
27752776
3541|[Find Most Frequent Vowel and Consonant](./solutions/3541-find-most-frequent-vowel-and-consonant.js)|Easy|
27762777

27772778
## License
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/**
2+
* 3539. Find Sum of Array Product of Magical Sequences
3+
* https://leetcode.com/problems/find-sum-of-array-product-of-magical-sequences/
4+
* Difficulty: Hard
5+
*
6+
* You are given two integers, m and k, and an integer array nums.
7+
*
8+
* A sequence of integers seq is called magical if:
9+
* - seq has a size of m.
10+
* - 0 <= seq[i] < nums.length
11+
* - The binary representation of 2seq[0] + 2seq[1] + ... + 2seq[m - 1] has k set bits.
12+
*
13+
* The array product of this sequence is defined as prod(seq) = (nums[seq[0]]
14+
* * nums[seq[1]] * ... * nums[seq[m - 1]]).
15+
*
16+
* Return the sum of the array products for all valid magical sequences.
17+
*
18+
* Since the answer may be large, return it modulo 109 + 7.
19+
*
20+
* A set bit refers to a bit in the binary representation of a number that has a value of 1.
21+
*/
22+
23+
/**
24+
* @param {number} m
25+
* @param {number} k
26+
* @param {number[]} nums
27+
* @return {number}
28+
*/
29+
var magicalSum = function(m, k, nums) {
30+
const MOD = 1000000007n;
31+
const map = new Map();
32+
const n = nums.length;
33+
34+
function bitCount(num) {
35+
let count = 0;
36+
while (num > 0) {
37+
count += num & 1;
38+
num >>= 1;
39+
}
40+
return count;
41+
}
42+
43+
function modPow(base, exp) {
44+
let result = 1n;
45+
base = BigInt(base) % MOD;
46+
let e = BigInt(exp);
47+
while (e > 0n) {
48+
if (e & 1n) result = (result * base) % MOD;
49+
base = (base * base) % MOD;
50+
e >>= 1n;
51+
}
52+
return result;
53+
}
54+
55+
const factorialCache = [1n];
56+
function factorial(n) {
57+
while (factorialCache.length <= n) {
58+
factorialCache.push(
59+
factorialCache[factorialCache.length - 1] * BigInt(factorialCache.length)
60+
);
61+
}
62+
return factorialCache[n];
63+
}
64+
65+
function comb(n, r) {
66+
if (r > n || r < 0) return 0n;
67+
if (r === 0 || r === n) return 1n;
68+
return factorial(n) / (factorial(r) * factorial(n - r));
69+
}
70+
71+
function dfs(remaining, oddNeeded, index, carry) {
72+
if (remaining < 0 || oddNeeded < 0 || remaining + bitCount(carry) < oddNeeded) {
73+
return 0n;
74+
}
75+
if (remaining === 0) {
76+
return bitCount(carry) === oddNeeded ? 1n : 0n;
77+
}
78+
if (index >= n) {
79+
return 0n;
80+
}
81+
82+
const key = `${remaining},${oddNeeded},${index},${carry}`;
83+
if (map.has(key)) return map.get(key);
84+
85+
let result = 0n;
86+
for (let take = 0; take <= remaining; take++) {
87+
const ways = (comb(remaining, take) * modPow(nums[index], take)) % MOD;
88+
const newCarry = carry + take;
89+
const contribution = dfs(
90+
remaining - take, oddNeeded - (newCarry % 2),
91+
index + 1, Math.floor(newCarry / 2),
92+
);
93+
result = (result + ways * contribution) % MOD;
94+
}
95+
96+
map.set(key, result);
97+
return result;
98+
}
99+
100+
return Number(dfs(m, k, 0, 0));
101+
};

0 commit comments

Comments
 (0)