Skip to content

Commit 4631634

Browse files
authored
Improved task 2902
1 parent 2db4ad4 commit 4631634

File tree

1 file changed

+54
-46
lines changed
  • src/main/java/g2901_3000/s2902_count_of_sub_multisets_with_bounded_sum

1 file changed

+54
-46
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,77 @@
11
package g2901_3000.s2902_count_of_sub_multisets_with_bounded_sum;
22

33
// #Hard #Array #Hash_Table #Dynamic_Programming #Sliding_Window
4-
// #2023_12_26_Time_2146_ms_(5.39%)_Space_70.7_MB_(23.08%)
4+
// #2023_12_29_Time_17_ms_(100.00%)_Space_45.4_MB_(59.02%)
55

6-
import java.util.ArrayList;
7-
import java.util.Collections;
8-
import java.util.HashMap;
96
import java.util.List;
107

118
public class Solution {
12-
private static final int MOD = (int) 1e9 + 7;
13-
private HashMap<Integer, Integer> map;
14-
private int[][] dp;
9+
private static final int MOD = 1000000007;
10+
private static final int MAX = 20001;
11+
private static final IntMap INT_MAP = new IntMap();
1512

16-
private int solve(List<Integer> al, int l, int r, int index, int sum) {
17-
if (sum > r) {
13+
public int countSubMultisets(List<Integer> nums, int l, int r) {
14+
INT_MAP.clear();
15+
INT_MAP.add(0);
16+
int total = 0;
17+
for (int num : nums) {
18+
INT_MAP.add(num);
19+
total += num;
20+
}
21+
if (total < l) {
1822
return 0;
1923
}
20-
long ans = 0;
21-
if (index >= al.size()) {
22-
return (int) ans;
24+
r = Math.min(r, total);
25+
final int[] cnt = new int[r + 1];
26+
cnt[0] = INT_MAP.map[0];
27+
int sum = 0;
28+
for (int i = 1; i < INT_MAP.size; i++) {
29+
final int val = INT_MAP.vals[i];
30+
final int count = INT_MAP.map[val];
31+
if (count > 0) {
32+
sum = Math.min(r, sum + val * count);
33+
update(cnt, val, count, sum);
34+
}
2335
}
24-
if (dp[index][sum] != -1) {
25-
return dp[index][sum];
36+
int res = 0;
37+
for (int i = l; i <= r; i++) {
38+
res = (res + cnt[i]) % MOD;
2639
}
27-
int cur = al.get(index);
28-
int count = map.get(cur);
29-
for (int i = 0; i <= count; i++) {
30-
int curSum = sum + cur * i;
31-
if (curSum > r) {
32-
break;
40+
return res;
41+
}
42+
43+
private static void update(final int[] cnt, final int n, final int count, final int sum) {
44+
if (count == 1) {
45+
for (int i = sum; i >= n; i--) {
46+
cnt[i] = (cnt[i] + cnt[i - n]) % MOD;
3347
}
34-
ans = ans + solve(al, l, r, index + 1, curSum);
35-
if (i != 0 && curSum >= l) {
36-
ans = ans + 1;
48+
} else {
49+
for (int i = n; i <= sum; i++) {
50+
cnt[i] = (cnt[i] + cnt[i - n]) % MOD;
51+
}
52+
final int max = (count + 1) * n;
53+
for (int i = sum; i >= max; i--) {
54+
cnt[i] = (cnt[i] - cnt[i - max] + MOD) % MOD;
3755
}
38-
ans = ans % MOD;
3956
}
40-
dp[index][sum] = (int) ans;
41-
return (int) ans;
4257
}
4358

44-
public int countSubMultisets(List<Integer> nums, int l, int r) {
45-
map = new HashMap<>();
46-
List<Integer> al = new ArrayList<>();
47-
for (int cur : nums) {
48-
int count = map.getOrDefault(cur, 0) + 1;
49-
map.put(cur, count);
50-
if (count == 1) {
51-
al.add(cur);
59+
private static final class IntMap {
60+
final int[] map = new int[MAX];
61+
final int[] vals = new int[MAX];
62+
int size = 0;
63+
64+
void add(int v) {
65+
if (map[v]++ == 0) {
66+
vals[size++] = v;
5267
}
5368
}
54-
int n = al.size();
55-
dp = new int[n][r + 1];
56-
for (int i = 0; i < dp.length; i++) {
57-
for (int j = 0; j < dp[0].length; j++) {
58-
dp[i][j] = -1;
69+
70+
void clear() {
71+
for (int i = 0; i < size; i++) {
72+
map[vals[i]] = 0;
5973
}
74+
size = 0;
6075
}
61-
Collections.sort(al);
62-
int ans = solve(al, l, r, 0, 0);
63-
if (l == 0) {
64-
ans = ans + 1;
65-
}
66-
ans = ans % MOD;
67-
return ans;
6876
}
6977
}

0 commit comments

Comments
 (0)