2025-10-12 Daily Challenge
Today I have done leetcode's October LeetCoding Challenge with cpp.
October LeetCoding Challenge 12
Description
Find Sum of Array Product of Magical Sequences
You are given two integers, m and k, and an integer array nums.
seq is called magical if:
seqhas a size ofm.0 <= seq[i] < nums.length- The binary representation of
2seq[0] + 2seq[1] + ... + 2seq[m - 1]haskset bits.
The array product of this sequence is defined as prod(seq) = (nums[seq[0]] * nums[seq[1]] * ... * nums[seq[m - 1]]).
Return the sum of the array products for all valid magical sequences.
Since the answer may be large, return it modulo 109 + 7.
A set bit refers to a bit in the binary representation of a number that has a value of 1.
Example 1:
Input: m = 5, k = 5, nums = [1,10,100,10000,1000000]
Output: 991600007
Explanation:
All permutations of [0, 1, 2, 3, 4] are magical sequences, each with an array product of 1013.
Example 2:
Input: m = 2, k = 2, nums = [5,4,3,2,1]
Output: 170
Explanation:
The magical sequences are [0, 1], [0, 2], [0, 3], [0, 4], [1, 0], [1, 2], [1, 3], [1, 4], [2, 0], [2, 1], [2, 3], [2, 4], [3, 0], [3, 1], [3, 2], [3, 4], [4, 0], [4, 1], [4, 2], and [4, 3].
Example 3:
Input: m = 1, k = 1, nums = [28]
Output: 28
Explanation:
The only magical sequence is [0].
Constraints:
1 <= k <= m <= 301 <= nums.length <= 501 <= nums[i] <= 108
Solution
class Solution {
using ll = long long;
const int MOD = 1e9 + 7;
ll dp[55][35][35][35] = {};
bool vis[55][35][35][35] = {};
vector<vector<ll>> powNum;
vector<vector<ll>> C;
int len;
int k;
int m;
void init(const vector<int>& nums) {
powNum.resize(len, vector<ll>(m + 1, 1));
for(int i = 0; i < len; ++i) {
for(int j = 1; j <= m; ++j) {
powNum[i][j] = powNum[i][j - 1] * nums[i] % MOD;
}
}
C.resize(m + 1, vector<ll>(m + 1));
for(int i = 0; i <= m; ++i) {
C[i][0] = C[i][i] = 1;
for(int j = 1; j < i; ++j) {
C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
}
}
}
ll dfs(int pos, int carry, int used, int ones) {
if(pos == len) {
int extra = 0;
int c = carry;
while(c) {
if(c & 1) extra += 1;
c >>= 1;
}
return (used == m && ones + extra == k) ? 1 : 0;
}
if(dp[pos][carry][used][ones] != -1) return dp[pos][carry][used][ones];
ll answer = 0;
for(int count = 0; count + used <= m; ++count) {
int total = carry + count;
int bit = total & 1;
int ncarry = total >> 1;
int nones = ones + bit;
ll sub = dfs(pos + 1, ncarry, used + count, nones);
if(!sub) continue;
ll ways = C[m - used][count];
ll prod = powNum[pos][count];
answer += sub * ways % MOD * prod % MOD;
answer %= MOD;
}
// cout << pos << ' ' << carry << ' ' << used << ' ' << ones << ' ' << answer << endl;
return dp[pos][carry][used][ones] = answer;
}
public:
int magicalSum(int m, int k, vector<int>& nums) {
memset(dp, -1, sizeof(dp));
this->m = m;
this->k = k;
len = nums.size();
init(nums);
return dfs(0, 0, 0, 0);
}
};
// Accepted
// 528/528 cases passed (700 ms)
// Your runtime beats 8.57 % of cpp submissions
// Your memory usage beats 40 % of cpp submissions (45.2 MB)