Skip to content

Commit 606aeda

Browse files
authored
Improved task 2902
1 parent 16ae309 commit 606aeda

File tree

1 file changed

+58
-44
lines changed
  • src/main/kotlin/g2901_3000/s2902_count_of_sub_multisets_with_bounded_sum

1 file changed

+58
-44
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,81 @@
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_27_Time_2416_ms_(100.00%)_Space_87.8_MB_(100.00%)
4+
// #2023_12_31_Time_249_ms_(100.00%)_Space_41.2_MB_(100.00%)
55

6-
class Solution {
7-
private var map: HashMap<Int, Int>? = null
8-
private lateinit var dp: Array<IntArray>
6+
import kotlin.math.min
97

10-
private fun solve(al: List<Int>, l: Int, r: Int, index: Int, sum: Int): Int {
11-
if (sum > r) {
8+
@Suppress("NAME_SHADOWING")
9+
class Solution {
10+
fun countSubMultisets(nums: List<Int>, l: Int, r: Int): Int {
11+
var r = r
12+
INT_MAP.clear()
13+
INT_MAP.add(0)
14+
var total = 0
15+
for (num in nums) {
16+
INT_MAP.add(num)
17+
total += num
18+
}
19+
if (total < l) {
1220
return 0
1321
}
14-
var ans: Long = 0
15-
if (index >= al.size) {
16-
return ans.toInt()
22+
r = min(r, total)
23+
val cnt = IntArray(r + 1)
24+
cnt[0] = INT_MAP.map[0]
25+
var sum = 0
26+
for (i in 1 until INT_MAP.size) {
27+
val `val` = INT_MAP.vals[i]
28+
val count = INT_MAP.map[`val`]
29+
if (count > 0) {
30+
sum = min(r, sum + `val` * count)
31+
update(cnt, `val`, count, sum)
32+
}
1733
}
18-
if (dp[index][sum] != -1) {
19-
return dp[index][sum]
34+
var res = 0
35+
for (i in l..r) {
36+
res = (res + cnt[i]) % MOD
2037
}
21-
val cur = al[index]
22-
val count = map!![cur]!!
23-
for (i in 0..count) {
24-
val curSum = sum + cur * i
25-
if (curSum > r) {
26-
break
38+
return res
39+
}
40+
41+
private fun update(cnt: IntArray, n: Int, count: Int, sum: Int) {
42+
if (count == 1) {
43+
for (i in sum downTo n) {
44+
cnt[i] = (cnt[i] + cnt[i - n]) % MOD
45+
}
46+
} else {
47+
for (i in n..sum) {
48+
cnt[i] = (cnt[i] + cnt[i - n]) % MOD
2749
}
28-
ans += solve(al, l, r, index + 1, curSum)
29-
if (i != 0 && curSum >= l) {
30-
ans += 1
50+
val max = (count + 1) * n
51+
for (i in sum downTo max) {
52+
cnt[i] = (cnt[i] - cnt[i - max] + MOD) % MOD
3153
}
32-
ans %= MOD
3354
}
34-
dp[index][sum] = ans.toInt()
35-
return ans.toInt()
3655
}
3756

38-
fun countSubMultisets(nums: List<Int>, l: Int, r: Int): Int {
39-
map = HashMap()
40-
val al: MutableList<Int> = ArrayList()
41-
for (cur in nums) {
42-
val count = map!!.getOrDefault(cur, 0) + 1
43-
map!![cur] = count
44-
if (count == 1) {
45-
al.add(cur)
57+
private class IntMap {
58+
val map: IntArray = IntArray(MAX)
59+
val vals: IntArray = IntArray(MAX)
60+
var size: Int = 0
61+
62+
fun add(v: Int) {
63+
if (map[v]++ == 0) {
64+
vals[size++] = v
4665
}
4766
}
48-
val n = al.size
49-
dp = Array(n) { IntArray(r + 1) }
50-
for (i in dp.indices) {
51-
for (j in dp[0].indices) {
52-
dp[i][j] = -1
67+
68+
fun clear() {
69+
for (i in 0 until size) {
70+
map[vals[i]] = 0
5371
}
72+
size = 0
5473
}
55-
al.sort()
56-
var ans = solve(al, l, r, 0, 0)
57-
if (l == 0) {
58-
ans += 1
59-
}
60-
ans %= MOD
61-
return ans
6274
}
6375

6476
companion object {
65-
private const val MOD = 1e9.toInt() + 7
77+
private const val MOD = 1000000007
78+
private const val MAX = 20001
79+
private val INT_MAP = IntMap()
6680
}
6781
}

0 commit comments

Comments
 (0)