# 第 233 场周赛题解
# Q1 1800. 最大升序子数组和 (opens new window)
题目中要求的是连续的且元素值均为正数,因此直接把符合条件的子数组分别求和,取最大值即可。
class Solution1800 {
fun maxAscendingSum(nums: IntArray): Int {
var ans = nums[0]
var cur = nums[0]
for (i in 1 until nums.size) {
if (nums[i] > nums[i - 1]) {
cur += nums[i]
} else {
cur = nums[i]
}
ans = maxOf(ans, cur)
}
return ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Q2 1801. 积压订单中的订单总数 (opens new window)
没什么难度,但是非常麻烦的题目。直接优先级队列搞。
class Solution1801 {
fun getNumberOfBacklogOrders(orders: Array<IntArray>): Int {
val buy = PriorityQueue<IntArray>(compareByDescending { it[0] })
val sell = PriorityQueue<IntArray>(compareBy { it[0] })
orders.forEach {
if (it[2] == 0) {
buy.offer(it)
} else {
sell.offer(it)
}
while (sell.isNotEmpty() && buy.isNotEmpty() && sell.peek()[0] <= buy.peek()[0]) {
val sellItem = sell.poll()
val buyItem = buy.poll()
if (sellItem[1] == buyItem[1]) {
continue
} else if (sellItem[1] > buyItem[1]) {
sell.offer(intArrayOf(sellItem[0], sellItem[1] - buyItem[1], sellItem[2]))
} else {
buy.offer(intArrayOf(buyItem[0], buyItem[1] - sellItem[1], buyItem[2]))
}
}
}
val mod = 1000000007L
var ans = 0L
buy.forEach {
ans += it[1]
}
sell.forEach {
ans += it[1]
}
return (ans % mod).toInt()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Q3 1802. 有界数组中指定下标处的最大值 (opens new window)
直接用二分,就是最开始公式推导很麻烦,浪费了很多时间。
class Solution1802 {
fun maxValue(n: Int, index: Int, maxSum: Int): Int {
fun sum(start: Int, count: Int): Long {
if (count == 0) return 0L
val minCount = minOf(start, count)
var sum = start * minCount.toLong() - (minCount - 1) * minCount.toLong() / 2
if (count > minCount) sum += count - minCount
return sum
}
var l = 1
var r = maxSum - n + 1
while (l < r) {
val mid = l + (r - l + 1) / 2
val sumLeft = sum(mid - 1, index)
val sumRight = sum(mid, n - index)
if (sumLeft + sumRight <= maxSum) l = mid
else r = mid - 1
}
return l
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Q4 1803. 统计异或值在范围内的数对有多少 (opens new window)
class Solution1803 {
fun countPairs(nums: IntArray, low: Int, high: Int): Int {
val trie = Trie<Int>()
var ans = 0
nums.forEach {
ans += trie.smaller(it, high + 1)
ans -= trie.smaller(it, low)
trie.insertInt(it)
}
return ans
}
}
class Trie<T> {
class TrieNode<T>(val init: T? = null) {
val value: T? = init
val children: ArrayList<TrieNode<T>> = arrayListOf()
var isEnd = false
var cnt = 0
}
var root = TrieNode<T>()
}
fun Trie<Int>.insertInt(n: Int) {
var temp = this.root
for (i in 31 downTo 0) {
val x: Int = (n shr i) and 1
val item = temp.children.firstOrNull { it.value == x }
if (item == null)
temp.children.add(Trie.TrieNode(x))
temp = temp.children.first { it.value == x }
temp.cnt++
}
}
fun Trie<Int>.smaller(n: Int, k: Int): Int {
var count = 0
var node: Trie.TrieNode<Int>? = this.root
for (i in 31 downTo 0) {
if (node == null) {
return count
}
val x: Int = (n shr i) and 1
val y: Int = (k shr i) and 1
if (y == 1) {
if (node.children.firstOrNull { it.value == x } != null) {
count += node.children.first { it.value == x }.cnt
}
node = node.children.firstOrNull { it.value == 1 - x }
} else {
node = node.children.firstOrNull { it.value == x }
}
}
return count
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56