Welcome to Subscribe On Youtube
3145. Find Products of Elements of Big Array
Description
A powerful array for an integer x
is the shortest sorted array of powers of two that sum up to x
. For example, the powerful array for 11 is [1, 2, 8]
.
The array big_nums
is created by concatenating the powerful arrays for every positive integer i
in ascending order: 1, 2, 3, and so forth. Thus, big_nums
starts as [1, 2, 1, 2, 4, 1, 4, 2, 4, 1, 2, 4, 8, ...]
.
You are given a 2D integer matrix queries
, where for queries[i] = [fromi, toi, modi]
you should calculate (big_nums[fromi] * big_nums[fromi + 1] * ... * big_nums[toi]) % modi
.
Return an integer array answer
such that answer[i]
is the answer to the ith
query.
Example 1:
Input: queries = [[1,3,7]]
Output: [4]
Explanation:
There is one query.
big_nums[1..3] = [2,1,2]
. The product of them is 4. The remainder of 4 under 7 is 4.
Example 2:
Input: queries = [[2,5,3],[7,7,4]]
Output: [2,2]
Explanation:
There are two queries.
First query: big_nums[2..5] = [1,2,4,1]
. The product of them is 8. The remainder of 8 under 3 is 2.
Second query: big_nums[7] = 2
. The remainder of 2 under 4 is 2.
Constraints:
1 <= queries.length <= 500
queries[i].length == 3
0 <= queries[i][0] <= queries[i][1] <= 1015
1 <= queries[i][2] <= 105
Solutions
Solution 1
-
class Solution { private static final int M = 50; private static final long[] cnt = new long[M + 1]; private static final long[] s = new long[M + 1]; static { long p = 1; for (int i = 1; i <= M; i++) { cnt[i] = cnt[i - 1] * 2 + p; s[i] = s[i - 1] * 2 + p * (i - 1); p *= 2; } } private static long[] numIdxAndSum(long x) { long idx = 0; long totalSum = 0; while (x > 0) { int i = Long.SIZE - Long.numberOfLeadingZeros(x) - 1; idx += cnt[i]; totalSum += s[i]; x -= 1L << i; totalSum += (x + 1) * i; idx += x + 1; } return new long[] {idx, totalSum}; } private static long f(long i) { long l = 0; long r = 1L << M; while (l < r) { long mid = (l + r + 1) >> 1; long[] idxAndSum = numIdxAndSum(mid); long idx = idxAndSum[0]; if (idx < i) { l = mid; } else { r = mid - 1; } } long[] idxAndSum = numIdxAndSum(l); long totalSum = idxAndSum[1]; long idx = idxAndSum[0]; i -= idx; long x = l + 1; for (int j = 0; j < i; j++) { long y = x & -x; totalSum += Long.numberOfTrailingZeros(y); x -= y; } return totalSum; } public int[] findProductsOfElements(long[][] queries) { int n = queries.length; int[] ans = new int[n]; for (int i = 0; i < n; i++) { long left = queries[i][0]; long right = queries[i][1]; long mod = queries[i][2]; long power = f(right + 1) - f(left); ans[i] = qpow(2, power, mod); } return ans; } private int qpow(long a, long n, long mod) { long ans = 1 % mod; for (; n > 0; n >>= 1) { if ((n & 1) == 1) { ans = ans * a % mod; } a = a * a % mod; } return (int) ans; } }
-
using ll = long long; const int m = 50; ll cnt[m + 1]; ll s[m + 1]; ll p = 1; auto init = [] { cnt[0] = 0; s[0] = 0; for (int i = 1; i <= m; ++i) { cnt[i] = cnt[i - 1] * 2 + p; s[i] = s[i - 1] * 2 + p * (i - 1); p *= 2; } return 0; }(); pair<ll, ll> numIdxAndSum(ll x) { ll idx = 0; ll totalSum = 0; while (x > 0) { int i = 63 - __builtin_clzll(x); idx += cnt[i]; totalSum += s[i]; x -= 1LL << i; totalSum += (x + 1) * i; idx += x + 1; } return make_pair(idx, totalSum); } ll f(ll i) { ll l = 0; ll r = 1LL << m; while (l < r) { ll mid = (l + r + 1) >> 1; auto idxAndSum = numIdxAndSum(mid); ll idx = idxAndSum.first; if (idx < i) { l = mid; } else { r = mid - 1; } } auto idxAndSum = numIdxAndSum(l); ll totalSum = idxAndSum.second; ll idx = idxAndSum.first; i -= idx; ll x = l + 1; for (int j = 0; j < i; ++j) { ll y = x & -x; totalSum += __builtin_ctzll(y); x -= y; } return totalSum; } ll qpow(ll a, ll n, ll mod) { ll ans = 1 % mod; a = a % mod; while (n > 0) { if (n & 1) { ans = ans * a % mod; } a = a * a % mod; n >>= 1; } return ans; } class Solution { public: vector<int> findProductsOfElements(vector<vector<ll>>& queries) { int n = queries.size(); vector<int> ans(n); for (int i = 0; i < n; ++i) { ll left = queries[i][0]; ll right = queries[i][1]; ll mod = queries[i][2]; ll power = f(right + 1) - f(left); ans[i] = static_cast<int>(qpow(2, power, mod)); } return ans; } };
-
m = 50 cnt = [0] * (m + 1) s = [0] * (m + 1) p = 1 for i in range(1, m + 1): cnt[i] = cnt[i - 1] * 2 + p s[i] = s[i - 1] * 2 + p * (i - 1) p *= 2 def num_idx_and_sum(x: int) -> tuple: idx = 0 total_sum = 0 while x: i = x.bit_length() - 1 idx += cnt[i] total_sum += s[i] x -= 1 << i total_sum += (x + 1) * i idx += x + 1 return (idx, total_sum) def f(i: int) -> int: l, r = 0, 1 << m while l < r: mid = (l + r + 1) >> 1 idx, _ = num_idx_and_sum(mid) if idx < i: l = mid else: r = mid - 1 total_sum = 0 idx, total_sum = num_idx_and_sum(l) i -= idx x = l + 1 for _ in range(i): y = x & -x total_sum += y.bit_length() - 1 x -= y return total_sum class Solution: def findProductsOfElements(self, queries: List[List[int]]) -> List[int]: return [pow(2, f(right + 1) - f(left), mod) for left, right, mod in queries]
-
const m = 50 var cnt [m + 1]int64 var s [m + 1]int64 var p int64 = 1 func init() { cnt[0] = 0 s[0] = 0 for i := 1; i <= m; i++ { cnt[i] = cnt[i-1]*2 + p s[i] = s[i-1]*2 + p*(int64(i)-1) p *= 2 } } func numIdxAndSum(x int64) (int64, int64) { var idx, totalSum int64 for x > 0 { i := 63 - bits.LeadingZeros64(uint64(x)) idx += cnt[i] totalSum += s[i] x -= 1 << i totalSum += (x + 1) * int64(i) idx += x + 1 } return idx, totalSum } func f(i int64) int64 { l, r := int64(0), int64(1)<<m for l < r { mid := (l + r + 1) >> 1 idx, _ := numIdxAndSum(mid) if idx < i { l = mid } else { r = mid - 1 } } _, totalSum := numIdxAndSum(l) idx, _ := numIdxAndSum(l) i -= idx x := l + 1 for j := int64(0); j < i; j++ { y := x & -x totalSum += int64(bits.TrailingZeros64(uint64(y))) x -= y } return totalSum } func qpow(a, n, mod int64) int64 { ans := int64(1) % mod a = a % mod for n > 0 { if n&1 == 1 { ans = (ans * a) % mod } a = (a * a) % mod n >>= 1 } return ans } func findProductsOfElements(queries [][]int64) []int { ans := make([]int, len(queries)) for i, q := range queries { left, right, mod := q[0], q[1], q[2] power := f(right+1) - f(left) ans[i] = int(qpow(2, power, mod)) } return ans }