diff --git a/src/codeforces/set0/set9/set980/set985/c/problem.md b/src/codeforces/set0/set9/set980/set985/c/problem.md new file mode 100644 index 00000000..7532af0f --- /dev/null +++ b/src/codeforces/set0/set9/set980/set985/c/problem.md @@ -0,0 +1,9 @@ +You have m = n·k wooden staves. The i-th stave has length ai. You have to assemble n barrels consisting of k staves each, you can use any k staves to construct a barrel. Each stave must belong to exactly one barrel. + +Let volume vj of barrel j be equal to the length of the minimal stave in it. + + +You want to assemble exactly n barrels with the maximal total sum of volumes. But you have to make them equal enough, so a difference between volumes of any pair of the resulting barrels must not exceed l, i.e. |vx - vy| ≤ l for any 1 ≤ x ≤ n and 1 ≤ y ≤ n. + +Print maximal total sum of volumes of equal enough barrels or 0 if it's impossible to satisfy the condition above. + diff --git a/src/codeforces/set0/set9/set980/set985/c/solution.go b/src/codeforces/set0/set9/set980/set985/c/solution.go new file mode 100644 index 00000000..7c9e80dd --- /dev/null +++ b/src/codeforces/set0/set9/set980/set985/c/solution.go @@ -0,0 +1,109 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "sort" +) + +func main() { + reader := bufio.NewReader(os.Stdin) + n, k, l := readThreeNums(reader) + a := readNNums(reader, n*k) + fmt.Println(solve(a, k, l)) +} + +func readInt(bytes []byte, from int, val *int) int { + i := from + sign := 1 + if bytes[i] == '-' { + sign = -1 + i++ + } + tmp := 0 + for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' { + tmp = tmp*10 + int(bytes[i]-'0') + i++ + } + *val = tmp * sign + return i +} + +func readNum(reader *bufio.Reader) (a int) { + bs, _ := reader.ReadBytes('\n') + readInt(bs, 0, &a) + return +} + +func readTwoNums(reader *bufio.Reader) (a int, b int) { + res := readNNums(reader, 2) + a, b = res[0], res[1] + return +} + +func readThreeNums(reader *bufio.Reader) (a int, b int, c int) { + res := readNNums(reader, 3) + a, b, c = res[0], res[1], res[2] + return +} + +func readNNums(reader *bufio.Reader, n int) []int { + res := make([]int, n) + x := 0 + bs, _ := reader.ReadBytes('\n') + for i := 0; i < n; i++ { + for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' { + x++ + } + x = readInt(bs, x, &res[i]) + } + return res +} + +func solve(a []int, k int, l int) int { + sort.Ints(a) + + n := len(a) + + vis := make([]bool, n) + + it := sort.Search(n, func(i int) bool { + return a[i]-a[0] > l + }) + if it < n/k { + return 0 + } + it-- + // a[it] - a[0] <= l + var res int + r := n - 1 + // stage 1 + for i := it; i >= 0; i-- { + if r-it < k-1 { + break + } + var cnt int + for cnt < k-1 { + vis[r] = true + cnt++ + r-- + } + res += a[i] + vis[i] = true + } + + for i := n - 1; i >= 0; { + var cnt int + for i >= 0 && cnt < k { + if !vis[i] { + cnt++ + } + i-- + } + if cnt == k { + res += a[i+1] + } + } + return res +} diff --git a/src/codeforces/set0/set9/set980/set985/c/solution_test.go b/src/codeforces/set0/set9/set980/set985/c/solution_test.go new file mode 100644 index 00000000..20a34e2d --- /dev/null +++ b/src/codeforces/set0/set9/set980/set985/c/solution_test.go @@ -0,0 +1,39 @@ +package main + +import "testing" + +func runSample(t *testing.T, a []int, k int, l int, expect int) { + res := solve(a, k, l) + + if res != expect { + t.Fatalf("Sample expect %d, but got %d", expect, res) + } +} + +func TestSample1(t *testing.T) { + k, l := 2, 1 + a := []int{2, 2, 1, 2, 3, 2, 2, 3} + expect := 7 + runSample(t, a, k, l, expect) +} + +func TestSample2(t *testing.T) { + k, l := 1, 0 + a := []int{10, 10} + expect := 20 + runSample(t, a, k, l, expect) +} + +func TestSample3(t *testing.T) { + k, l := 2, 1 + a := []int{5, 2} + expect := 2 + runSample(t, a, k, l, expect) +} + +func TestSample4(t *testing.T) { + k, l := 2, 1 + a := []int{1, 2, 3, 4, 5, 6} + expect := 0 + runSample(t, a, k, l, expect) +} diff --git a/src/codeforces/set1/set17/set179/set1793/d/problem.md b/src/codeforces/set1/set17/set179/set1793/d/problem.md new file mode 100644 index 00000000..dc7f0fca --- /dev/null +++ b/src/codeforces/set1/set17/set179/set1793/d/problem.md @@ -0,0 +1,60 @@ +In winter, the inhabitants of the Moscow Zoo are very bored, in particular, it concerns gorillas. You decided to entertain them and brought a permutation 𝑝 + of length 𝑛 + to the zoo. + +A permutation of length 𝑛 + is an array consisting of 𝑛 + distinct integers from 1 + to 𝑛 + in any order. For example, [2,3,1,5,4] + is a permutation, but [1,2,2] + is not a permutation (2 + occurs twice in the array) and [1,3,4] + is also not a permutation (𝑛=3 +, but 4 + is present in the array). + +The gorillas had their own permutation 𝑞 + of length 𝑛 +. They suggested that you count the number of pairs of integers 𝑙,𝑟 + (1≤𝑙≤𝑟≤𝑛 +) such that MEX([𝑝𝑙,𝑝𝑙+1,…,𝑝𝑟])=MEX([𝑞𝑙,𝑞𝑙+1,…,𝑞𝑟]) +. + +The MEX + of the sequence is the minimum integer positive number missing from this sequence. For example, MEX([1,3])=2 +, MEX([5])=1 +, MEX([3,1,2,6])=4 +. + +You do not want to risk your health, so you will not dare to refuse the gorillas. + + +### ideas +1. 略一思考,还有点难~ +2. 假设p[i] = 0, q[j] = 0, +3. 那么任何不包括(i, j)的区间[l...r]它们的mex = 0 +4. 那是不是就可以这样算呢? +5. 不包括(i, j)的区间 = 总区间数 n * (n + 1) / 2 - 包含它们的区间数 = (i+1) * (n - j) ? +6. 前面处理的是 mex = 0的情况, +7. 接下来处理mex = 1的情况(它们必须把0包括进去) +8. 好像不大对,比如如果0在两头的时候 +9. 那些mex = 0 的区间 = 肯定不包含任何一个0的区间 +10. 正难则反。有办法计算出,区间[l...r]中 mex(q) != mex(p)的方式吗? +11. 假设 mex(p[l..r]) = x, mex(q[l...r]) = y +12. 它们不相同 +13. 考虑一个序列,如何找到mex +14. 假设序列是 [2,3,1,5,4], +15. mex[3:3] = 2, 其他的等于 1 +16. mex[1:3] = 4, 其他的等于 1 +17. mex[1:5] = 6, 其他的等于1 +18. [1 3 2], [2 1 3] +19. p_mex[1:2] = 2, q_mex[1:2] = 3 但是其他都等于1 +20. p_mex[1:3] = 4, q_mex[1:3] = 4 +21. [4, 1, 3, 2], [4, 3, 1, 2] +22. [4, 1, 3] mex = 2 +23. [4, 3, 1] mex = 2 +24. 这个区间[1:3]它就是包含了1,但是不包含2,所以这样是这样的区间它们的mex = 2 +25. 所以如果某个区间包含了1....x-1, 但是不包含x,那么这样的区间是相等的 +26. mex = 0的区间假设已经get到了 +27. 那么计算 mex = x的区间,就可以用到上面的方式 \ No newline at end of file diff --git a/src/codeforces/set1/set17/set179/set1793/d/solution.go b/src/codeforces/set1/set17/set179/set1793/d/solution.go new file mode 100644 index 00000000..4baf0fb5 --- /dev/null +++ b/src/codeforces/set1/set17/set179/set1793/d/solution.go @@ -0,0 +1,128 @@ +package main + +import ( + "bufio" + "fmt" + "os" +) + +func main() { + reader := bufio.NewReader(os.Stdin) + + n := readNum(reader) + p := readNNums(reader, n) + q := readNNums(reader, n) + res := solve(p, q) + fmt.Println(res) +} + +func readString(reader *bufio.Reader) string { + s, _ := reader.ReadString('\n') + for i := 0; i < len(s); i++ { + if s[i] == '\n' || s[i] == '\r' { + return s[:i] + } + } + return s +} + +func readInt(bytes []byte, from int, val *int) int { + i := from + sign := 1 + if bytes[i] == '-' { + sign = -1 + i++ + } + tmp := 0 + for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' { + tmp = tmp*10 + int(bytes[i]-'0') + i++ + } + *val = tmp * sign + return i +} + +func readNum(reader *bufio.Reader) (a int) { + bs, _ := reader.ReadBytes('\n') + readInt(bs, 0, &a) + return +} + +func readTwoNums(reader *bufio.Reader) (a int, b int) { + res := readNNums(reader, 2) + a, b = res[0], res[1] + return +} + +func readThreeNums(reader *bufio.Reader) (a int, b int, c int) { + res := readNNums(reader, 3) + a, b, c = res[0], res[1], res[2] + return +} + +func readNNums(reader *bufio.Reader, n int) []int { + res := make([]int, n) + x := 0 + bs, _ := reader.ReadBytes('\n') + for i := 0; i < n; i++ { + for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' { + x++ + } + x = readInt(bs, x, &res[i]) + } + return res +} + +func solve(p []int, q []int) int { + n := len(p) + for i := 0; i < n; i++ { + p[i]-- + q[i]-- + } + + ps := getPosition(p) + qs := getPosition(q) + + first := min(ps[0], qs[0]) + last := max(ps[0], qs[0]) + + get := func(m int) int { + if m <= 0 { + return 0 + } + return m * (m + 1) / 2 + } + + // mex = 0 的区间 + var res int + res += get(first) + res += get(last - first - 1) + res += get(n - last - 1) + + for x := 1; x < n; x++ { + l := min(ps[x], qs[x]) + r := max(ps[x], qs[x]) + // mex = x的区间, 必须包含 [first...last], 但是不能包含(l, r) + if l < first && last < r { + res += (first - l) * (r - last) + } else if l > last { + res += (first + 1) * (l - last) + } else if r < first { + res += (first - r) * (n - last) + } + + first = min(first, l) + last = max(last, r) + } + + return res + 1 +} + +func getPosition(nums []int) []int { + n := len(nums) + pos := make([]int, n) + for i, num := range nums { + pos[num] = i + } + return pos +} diff --git a/src/codeforces/set1/set17/set179/set1793/d/solution_test.go b/src/codeforces/set1/set17/set179/set1793/d/solution_test.go new file mode 100644 index 00000000..d374c1bd --- /dev/null +++ b/src/codeforces/set1/set17/set179/set1793/d/solution_test.go @@ -0,0 +1,32 @@ +package main + +import "testing" + +func runSample(t *testing.T, p []int, q []int, expect int) { + res := solve(p, q) + + if res != expect { + t.Fatalf("Sample expect %d, but got %d", expect, res) + } +} + +func TestSample1(t *testing.T) { + a := []int{1, 3, 2} + b := []int{2, 1, 3} + expect := 2 + runSample(t, a, b, expect) +} + +func TestSample2(t *testing.T) { + a := []int{7, 3, 6, 2, 1, 5, 4} + b := []int{6, 7, 2, 5, 3, 1, 4} + expect := 16 + runSample(t, a, b, expect) +} + +func TestSample3(t *testing.T) { + a := []int{1, 2, 3, 4, 5, 6} + b := []int{6, 5, 4, 3, 2, 1} + expect := 11 + runSample(t, a, b, expect) +} diff --git a/src/codeforces/set1/set19/set190/set1906/f/problem.md b/src/codeforces/set1/set19/set190/set1906/f/problem.md new file mode 100644 index 00000000..3d306ce6 --- /dev/null +++ b/src/codeforces/set1/set19/set190/set1906/f/problem.md @@ -0,0 +1,110 @@ +You are given a one-based array consisting of 𝑁 + integers: 𝐴1,𝐴2,⋯,𝐴𝑁 +. Initially, the value of each element is set to 0 +. + +There are 𝑀 + operations (numbered from 1 + to 𝑀 +). Operation 𝑖 + is represented by ⟨𝐿𝑖,𝑅𝑖,𝑋𝑖⟩ +. If operation 𝑖 + is executed, all elements 𝐴𝑗 + for 𝐿𝑖≤𝑗≤𝑅𝑖 + will be increased by 𝑋𝑖 +. + +You have to answer 𝑄 + independent queries. Each query is represented by ⟨𝐾,𝑆,𝑇⟩ + which represents the following task. Choose a range [𝑙,𝑟] + satisfying 𝑆≤𝑙≤𝑟≤𝑇 +, and execute operations 𝑙,𝑙+1,…,𝑟 +. The answer to the query is the maximum value of 𝐴𝐾 + after the operations are executed among all possible choices of 𝑙 + and 𝑟 +. + +Input +The first line consists of two integers 𝑁 + 𝑀 + (1≤𝑁,𝑀≤100000 +). + +Each of the next 𝑀 + lines consists of three integers 𝐿𝑖 + 𝑅𝑖 + 𝑋𝑖 + (1≤𝐿𝑖≤𝑅𝑖≤𝑁;−100000≤𝑋𝑖≤100000 +). + +The following line consists of an integer 𝑄 + (1≤𝑄≤100000 +). + +Each of the next 𝑄 + lines consists of three integers 𝐾 + 𝑆 + 𝑇 + (1≤𝐾≤𝑁;1≤𝑆≤𝑇≤𝑀 +). + +Output +For each query, output in a single line, an integer which represent the answer of the query. + +### ideas +1. 感觉很难呐 +2. 单独的操作1,可以用range update +3. 把query 按照 T升序排 +4. 然后把operation和query一起处理,在处理完operation i后,处理T = i的query +5. 构建一个segment forest +6. 每个segment tree表示操作i后的状态 +7. 每个node维护两个信息,它在操作i后的value,在它前面最大的值,以及对应的操作是什么 +8. 上面的不大行 +9. 这里的关键是要知道k在操作区间[l...r]的最大值是什么 +10. 二维的segment tree? +11. 但是如何更新呢?这里更新的时候,是把一个区间的所有的值都更新掉 +12. 如果每个元素都更新, 肯定会成 n * m 的复杂性 +13. 假设不去更新,要怎么样知道这个信息呢? +14. 在每个节点上,把更新记录下来。但不真的更新 +15. 在查询的时候,把更新不断的push下去?但是只要push下去了,在最终的节点上,就发生了更新了 +16. 所以,还是不大对 +17. 对于区间[s...t],如果最大值出现在区间[l...r], 那么可以肯定的一点是 +18. [s...l-1] < 0 +19. [r+1....t] < 0 否则的话,只要把前缀或者后缀加入进去,就能获得更大的值 +20. 所以,从上面的分析可以得出这样一个结论,就是要找到最小的前缀[s...l) +21. 和最小的后缀 (r....t] +22. 剩下的部分就是最大值 +23. 不对~~~~ +24. 还是没有找到题眼~~~ +25. 假设有个数据结构,维护了足够的信息。在查询k的时候,如果能够确定k的操作和当前节点的操作是一致的 +26. 那么就不需要一路访问到k; +27. 比如操作 [1...5], [2...5], [2...4], 那么在查询k=3的时候,那么只要到达包含区间 [2...4]的节点时 +28. 就ok了 +29. 如果是要查询k=5, 那只需要到区间 [3...5] (因为它已经包含了操作1,2,且不包含操作3) +30. 假设发现node的左子节点为空,且需要go left, 那么是不是查询当前节点即可呢? +31. 好像是的呐 +32. 但是如何维护这个数据结构呢?另外一个segment tree? +33. 在push的时候,创建出来? +34. 搞不定, 不搞了~ + +### solution + +First, let’s discuss how to solve this problem if all of the K are same. +We can construct an auxiliary array B with size M which contains operations that can affect AK. +If K is not between Li and Ri +, then the value of array Bi +is 0. Otherwise, the value of array Bi +is +Xi +. By using array B, a query can then be answered by returning “the maximum subarray sum in +a given range” from this array. This query can be answered using a segment tree data structure. +Now, to solve the problem for any K, we can sort the queries based on K. Initially, we need to +construct a segment tree for the auxiliary array when K = 1 and answer all queries with K = +1. When transitioning to next K, we can avoid rebuilding the segment tree by only updating the +affected indices. If operation i has Ri = K, then we need to update Bi +to 0. Another case is if +operation i has Li = K + 1, then we need to update Bi +to Xi +. Each operation i will only update the +auxiliary array at most twice. +The total time complexity for this problem is O((Q + M) log M). \ No newline at end of file diff --git a/src/codeforces/set1/set19/set190/set1906/f/solution.go b/src/codeforces/set1/set19/set190/set1906/f/solution.go new file mode 100644 index 00000000..ef4d729e --- /dev/null +++ b/src/codeforces/set1/set19/set190/set1906/f/solution.go @@ -0,0 +1,262 @@ +package main + +import ( + "bufio" + "bytes" + "fmt" + "os" +) + +func main() { + reader := bufio.NewReader(os.Stdin) + + n, m := readTwoNums(reader) + operations := make([][]int, m) + for i := 0; i < m; i++ { + operations[i] = readNNums(reader, 3) + } + k := readNum(reader) + queries := make([][]int, k) + for i := 0; i < k; i++ { + queries[i] = readNNums(reader, 3) + } + res := solve(n, operations, queries) + + var buf bytes.Buffer + for _, x := range res { + buf.WriteString(fmt.Sprintf("%d\n", x)) + } + fmt.Print(buf.String()) +} + +func readString(reader *bufio.Reader) string { + s, _ := reader.ReadString('\n') + for i := 0; i < len(s); i++ { + if s[i] == '\n' || s[i] == '\r' { + return s[:i] + } + } + return s +} + +func readNInt64s(reader *bufio.Reader, n int) []int64 { + res := make([]int64, n) + s, _ := reader.ReadBytes('\n') + + var pos int + + for i := 0; i < n; i++ { + pos = readInt64(s, pos, &res[i]) + 1 + } + + return res +} + +func readInt64(bytes []byte, from int, val *int64) int { + i := from + var sign int64 = 1 + if bytes[i] == '-' { + sign = -1 + i++ + } + var tmp int64 + for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' { + tmp = tmp*10 + int64(bytes[i]-'0') + i++ + } + *val = tmp * sign + return i +} + +func readInt(bytes []byte, from int, val *int) int { + i := from + sign := 1 + if bytes[i] == '-' { + sign = -1 + i++ + } + tmp := 0 + for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' { + tmp = tmp*10 + int(bytes[i]-'0') + i++ + } + *val = tmp * sign + return i +} + +func readNum(reader *bufio.Reader) (a int) { + bs, _ := reader.ReadBytes('\n') + readInt(bs, 0, &a) + return +} + +func readTwoNums(reader *bufio.Reader) (a int, b int) { + res := readNNums(reader, 2) + a, b = res[0], res[1] + return +} + +func readThreeNums(reader *bufio.Reader) (a int, b int, c int) { + res := readNNums(reader, 3) + a, b, c = res[0], res[1], res[2] + return +} + +func readNNums(reader *bufio.Reader, n int) []int { + res := make([]int, n) + x := 0 + bs, _ := reader.ReadBytes('\n') + for i := 0; i < n; i++ { + for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' { + x++ + } + x = readInt(bs, x, &res[i]) + } + return res +} + +func solve(n int, operations [][]int, queries [][]int) []int { + m := len(operations) + qn := len(queries) + qr := make([][]int, n) + + for i, cur := range queries { + k := cur[0] - 1 + qr[k] = append(qr[k], i) + } + + open := make([][]int, n) + end := make([][]int, n) + + for i, op := range operations { + l, r := op[0]-1, op[1]-1 + open[l] = append(open[l], i) + end[r] = append(end[r], i) + } + + tr := NewTree(m) + + ans := make([]int, qn) + + for k := 0; k < n; k++ { + for _, i := range open[k] { + x := operations[i][2] + tr.Update(i, x, true) + } + + for _, i := range qr[k] { + l, r := queries[i][1]-1, queries[i][2] + tmp := tr.Get(l, r) + if tmp.cnt < r-l { + // 如果k没有被l...r的所有的操作覆盖,那么它可以取值为0 + // 否则的话,它必须根据这些操作的最小值(有可能是负数) + tmp.f00 = max(tmp.f00, 0) + } + ans[i] = tmp.f00 + } + + for _, i := range end[k] { + x := operations[i][2] + tr.Update(i, x, false) + } + } + + return ans +} + +type Node struct { + f00 int + f01 int + f10 int + f11 int + cnt int +} + +func (node *Node) updateValue(v, w int) { + node.f00 = v + node.f01 = v + node.f10 = v + node.f11 = v + node.cnt = w +} + +func NewNode(v int) *Node { + node := new(Node) + node.f00 = v + node.f01 = v + node.f10 = v + node.f11 = v + return node +} + +func unit() *Node { + node := NewNode(-inf) + node.f11 = 0 + node.cnt = 0 + return node +} + +const inf = 1 << 50 + +func maintain(left, right *Node) *Node { + node := unit() + node.f00 = max(-inf, left.f00, right.f00, left.f01+right.f10) + node.f10 = max(-inf, left.f10, left.f11+right.f10) + node.f01 = max(-inf, right.f01, left.f01+right.f11) + node.f11 = left.f11 + right.f11 + node.cnt = left.cnt + right.cnt + return node +} + +type Tree struct { + nodes []*Node + sz int +} + +func NewTree(n int) *Tree { + arr := make([]*Node, 2*n) + for i := 0; i < 2*n; i++ { + arr[i] = unit() + } + + return &Tree{arr, n} +} + +func (tr *Tree) Update(pos int, v int, add bool) { + pos += tr.sz + + if add { + tr.nodes[pos].updateValue(v, 1) + } else { + tr.nodes[pos].updateValue(-inf, 0) + tr.nodes[pos].f11 = 0 + } + + for pos > 1 { + pos >>= 1 + tr.nodes[pos] = maintain(tr.nodes[pos*2], tr.nodes[pos*2+1]) + } +} + +func (tr *Tree) Get(l int, r int) *Node { + l += tr.sz + r += tr.sz + // 这边左右是有关系的 + ra := unit() + rb := unit() + + for l < r { + if l&1 == 1 { + ra = maintain(ra, tr.nodes[l]) + l++ + } + if r&1 == 1 { + r-- + rb = maintain(tr.nodes[r], rb) + } + l >>= 1 + r >>= 1 + } + + return maintain(ra, rb) +} diff --git a/src/codeforces/set1/set19/set190/set1906/f/solution_test.go b/src/codeforces/set1/set19/set190/set1906/f/solution_test.go new file mode 100644 index 00000000..d89b4ad4 --- /dev/null +++ b/src/codeforces/set1/set19/set190/set1906/f/solution_test.go @@ -0,0 +1,56 @@ +package main + +import ( + "reflect" + "testing" +) + +func runSample(t *testing.T, n int, operations [][]int, queries [][]int, expect []int) { + res := solve(n, operations, queries) + + if !reflect.DeepEqual(res, expect) { + t.Fatalf("Sample expect %v, but got %v", expect, res) + } +} + +func TestSample1(t *testing.T) { + n := 2 + operations := [][]int{ + {1, 1, -50}, + {1, 2, -20}, + {2, 2, -30}, + {1, 1, 60}, + {1, 2, 40}, + {2, 2, 10}, + } + queries := [][]int{ + {1, 1, 6}, + {2, 1, 6}, + {1, 1, 3}, + {2, 1, 3}, + {1, 1, 2}, + } + expect := []int{100, 50, 0, 0, -20} + + runSample(t, n, operations, queries, expect) +} + +func TestSample2(t *testing.T) { + n := 5 + operations := [][]int{ + {1, 3, 3}, + {2, 4, -2}, + {3, 5, 3}, + } + queries := [][]int{ + {1, 1, 3}, + {2, 1, 3}, + {3, 1, 3}, + {3, 2, 3}, + {2, 2, 3}, + {2, 2, 2}, + } + expect := []int{3, 3, 4, 3, 0, -2} + + runSample(t, n, operations, queries, expect) +} diff --git a/src/codeforces/set1/set19/set191/set1913/d/solution.go b/src/codeforces/set1/set19/set191/set1913/d/solution.go index 601ad0ff..9a6767f0 100644 --- a/src/codeforces/set1/set19/set191/set1913/d/solution.go +++ b/src/codeforces/set1/set19/set191/set1913/d/solution.go @@ -98,6 +98,46 @@ func sub(a, b int) int { func solve(a []int) int { n := len(a) + + dp := make([]int, n+1) + pref := make([]int, n+1) + stack := make([]int, n+1) + var top int + top++ + + dp[0] = 1 + pref[0] = 1 + sum := 1 + for i := 1; i < n; i++ { + for top > 0 && a[stack[top-1]] > a[i] { + sum = sub(sum, dp[stack[top-1]]) + top-- + } + if top == 0 { + dp[i] = add(1, pref[i-1]) + } else { + dp[i] = add(sum, sub(pref[i-1], pref[stack[top-1]])) + } + stack[top] = i + top++ + sum = add(sum, dp[i]) + pref[i] = add(pref[i-1], dp[i]) + } + + var res int + mn := 1 << 30 + for i := n - 1; i >= 0; i-- { + mn = min(mn, a[i]) + if a[i] == mn { + res = add(res, dp[i]) + } + } + + return res +} + +func solve1(a []int) int { + n := len(a) sum := make([]int, n+2) dp := make([]int, n+2) diff --git a/src/codeforces/set1/set19/set196/set1969/c/problem.md b/src/codeforces/set1/set19/set196/set1969/c/problem.md new file mode 100644 index 00000000..2eeaf948 --- /dev/null +++ b/src/codeforces/set1/set19/set196/set1969/c/problem.md @@ -0,0 +1,56 @@ +You are given an integer array 𝑎 + of length 𝑛 +. + +You can perform the following operation: choose an element of the array and replace it with any of its neighbor's value. + +For example, if 𝑎=[3,1,2] +, you can get one of the arrays [3,3,2] +, [3,2,2] + and [1,1,2] + using one operation, but not [2,1,2 +] or [3,4,2] +. + +Your task is to calculate the minimum possible total sum of the array if you can perform the aforementioned operation at most 𝑘 + times. + +Input +The first line contains a single integer 𝑡 + (1≤𝑡≤104 +) — the number of test cases. + +The first line of each test case contains two integers 𝑛 + and 𝑘 + (1≤𝑛≤3⋅105 +; 0≤𝑘≤10 +). + +The second line contains 𝑛 + integers 𝑎1,𝑎2,…,𝑎𝑛 + (1≤𝑎𝑖≤109 +). + +Additional constraint on the input: the sum of 𝑛 + over all test cases doesn't exceed 3⋅105 +. + + +### ideas +1. 如果只有一次操作,那么最优的方案是,选择 a[i] - a[i+1] 最大的进行替换(a[i] - a[i-1]) +2. k是10次,那可以换个dp的思路了 +3. dp[i][j] 表示到i为止进行了j次替换后的最优解 +4. 还需要知道a[i]现在等于多少,它不可能等于很远的数,距离不会超过j +5. dp[i][j][l] 表示到i为止,进行j次替换后的最后解,且a[i] 现在的值等于附近 i + l 处的值,l可以是负值 +6. dp[i+1][j][-1] 表示i+1处的值更改为a[i+2] +7. dp[i+1][j+x][-x] 表示 i+1处的值更改为 a[i+1-x],但是这个时候,中间的都必须被修改掉 +8. dp[i+1][j+x][-x] = dp[i][j+x][-(x+1)] (i+1不进行操作) 且a[i]的值 = a[i+x+1] +9. dp[i+1][j+x][x] = dp[i][j+x-1][x-1] 如果 a[i] = a[i-x] +10. dp[i+1][j][0] = min(dp[i][j][x], x >= 0) a[i]等于它前面的值,且i+1不操作 +11. 这个dp这么复杂吗? +12. 再想想,上面的做法不大对 +13. 假设a[i]用来替换别的数,那么它没有被替换的道理 +14. dp[i][j]表示在i前面使用了j次替换后的最小的前缀和 +15. 假设现在要计算 dp[i][j], 那么就是使用i(包括i)前面的某个下标l 且a[l]是[l...i]的最小值 +16. 去替换 a[l...i] +17. 并使用 a[l] 去替换前面的一个序列 \ No newline at end of file diff --git a/src/codeforces/set1/set19/set196/set1969/c/solution.go b/src/codeforces/set1/set19/set196/set1969/c/solution.go new file mode 100644 index 00000000..b36942d6 --- /dev/null +++ b/src/codeforces/set1/set19/set196/set1969/c/solution.go @@ -0,0 +1,118 @@ +package main + +import ( + "bufio" + "bytes" + "fmt" + "os" +) + +func main() { + reader := bufio.NewReader(os.Stdin) + + tc := readNum(reader) + + var buf bytes.Buffer + + for tc > 0 { + tc-- + n, k := readTwoNums(reader) + a := readNNums(reader, n) + res := solve(a, k) + buf.WriteString(fmt.Sprintf("%d\n", res)) + } + + fmt.Print(buf.String()) +} + +func readString(reader *bufio.Reader) string { + s, _ := reader.ReadString('\n') + for i := 0; i < len(s); i++ { + if s[i] == '\n' || s[i] == '\r' { + return s[:i] + } + } + return s +} + +func readInt(bytes []byte, from int, val *int) int { + i := from + sign := 1 + if bytes[i] == '-' { + sign = -1 + i++ + } + tmp := 0 + for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' { + tmp = tmp*10 + int(bytes[i]-'0') + i++ + } + *val = tmp * sign + return i +} + +func readNum(reader *bufio.Reader) (a int) { + bs, _ := reader.ReadBytes('\n') + readInt(bs, 0, &a) + return +} + +func readTwoNums(reader *bufio.Reader) (a int, b int) { + res := readNNums(reader, 2) + a, b = res[0], res[1] + return +} + +func readThreeNums(reader *bufio.Reader) (a int, b int, c int) { + res := readNNums(reader, 3) + a, b, c = res[0], res[1], res[2] + return +} + +func readNNums(reader *bufio.Reader, n int) []int { + res := make([]int, n) + x := 0 + bs, _ := reader.ReadBytes('\n') + for i := 0; i < n; i++ { + for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' { + x++ + } + x = readInt(bs, x, &res[i]) + } + return res +} + +const inf = 1 << 60 + +func solve(a []int, k int) int { + n := len(a) + + dp := make([][]int, n+1) + for i := 0; i <= n; i++ { + dp[i] = make([]int, k+1) + for j := 0; j <= k; j++ { + dp[i][j] = inf + } + } + + dp[0][0] = 0 + + for i := 0; i < n; i++ { + for j := 0; j <= k; j++ { + dp[i+1][j] = dp[i][j] + a[i] + // 或者使用a[i]去替换前面的值 + // 或者用前面的某个值来替换a[i] + mv := a[i] + + for ii := i; ii >= 0 && i-ii <= j; ii-- { + mv = min(mv, a[ii]) + dp[i+1][j] = min(dp[i+1][j], dp[ii][j-(i-ii)]+(i-ii+1)*mv) + } + if j > 0 { + dp[i+1][j] = min(dp[i+1][j], dp[i+1][j-1]) + } + } + } + + return dp[n][k] +} diff --git a/src/codeforces/set1/set19/set196/set1969/c/solution_test.go b/src/codeforces/set1/set19/set196/set1969/c/solution_test.go new file mode 100644 index 00000000..d0e201f8 --- /dev/null +++ b/src/codeforces/set1/set19/set196/set1969/c/solution_test.go @@ -0,0 +1,39 @@ +package main + +import "testing" + +func runSample(t *testing.T, a []int, k int, expect int) { + res := solve(a, k) + + if res != expect { + t.Fatalf("Sample expect %d, but got %d", expect, res) + } +} + +func TestSample1(t *testing.T) { + k := 1 + a := []int{3, 1, 2} + expect := 4 + runSample(t, a, k, expect) +} + +func TestSample2(t *testing.T) { + k := 3 + a := []int{5} + expect := 5 + runSample(t, a, k, expect) +} + +func TestSample3(t *testing.T) { + k := 2 + a := []int{2, 2, 1, 3} + expect := 5 + runSample(t, a, k, expect) +} + +func TestSample4(t *testing.T) { + k := 3 + a := []int{4, 1, 2, 2, 4, 3} + expect := 10 + runSample(t, a, k, expect) +} diff --git a/src/codeforces/set1/set19/set196/set1969/d/problem.md b/src/codeforces/set1/set19/set196/set1969/d/problem.md new file mode 100644 index 00000000..e59e04a3 --- /dev/null +++ b/src/codeforces/set1/set19/set196/set1969/d/problem.md @@ -0,0 +1,60 @@ +Alice and Bob are playing a game in the shop. There are 𝑛 + items in the shop; each item has two parameters: 𝑎𝑖 + (item price for Alice) and 𝑏𝑖 + (item price for Bob). + +Alice wants to choose a subset (possibly empty) of items and buy them. After that, Bob does the following: + +if Alice bought less than 𝑘 + items, Bob can take all of them for free; +otherwise, he will take 𝑘 + items for free that Alice bought (Bob chooses which 𝑘 + items it will be), and for the rest of the chosen items, Bob will buy them from Alice and pay 𝑏𝑖 + for the 𝑖 +-th item. +Alice's profit is equal to ∑𝑖∈𝑆𝑏𝑖−∑𝑗∈𝑇𝑎𝑗 +, where 𝑆 + is the set of items Bob buys from Alice, and 𝑇 + is the set of items Alice buys from the shop. In other words, Alice's profit is the difference between the amount Bob pays her and the amount she spends buying the items. + +Alice wants to maximize her profit, Bob wants to minimize Alice's profit. Your task is to calculate Alice's profit if both Alice and Bob act optimally. + +### ideas +1. alice选择少于k个没啥意义。因为这时候他的收益是负的。不如啥都不选,收益等于0 +2. 所以,alice肯定选了 > k 个 +3. 在选择了m个以后,成本等于sum(a), 收益等于 sum(b least (m - k)) 个 +4. 但是从n个里面选择m个,这个复杂性太高。 +5. 还需要观察 +6. 如果按照b降序排,确实可以很快的计算出收益,但却不一定是成本最低的 +7. 选择最贵b个(它们肯定会被free掉)但是它们的成本却不一定是最低的 +8. 保证成本最低的时候,(按照a升序),却不一定能保证收益 +9. 如果一个item b[i]极大,但是 a[i]极小,那么它肯定应该被选中 +10. 难道就是把所有b[i] - a[i] >= 0选中就可以了吗? +11. 然后那些 b[i] - a[i] < 0的部分,假设选中了,且b[i] > 所有其他的,那么它的贡献就是-a[i] +12. 显然是不划算的,如果 b[i]不是最大的那部分,它同样不会有贡献 + +### solution +Let's sort the array in descending order based on the array 𝑏 +. For a fixed set of Alice's items, Bob will take the first 𝑘 + of them for free (because they are the most expensive) and pay for the rest. + +Now we can iterate over the first item that Bob will pay (denote it as 𝑖 +). Alice has to buy the cheapest 𝑘 + items among 1,2,…,𝑖−1 + (denote the sum of these values as 𝑓 +), because Bob can take them for free. Bob has to pay for each of the items among 𝑖,𝑖+1,…,𝑛 + that Alice will buy. So Alice will buy all the items with 𝑏𝑖−𝑎𝑖>0 + (denote the sum of these values as 𝑝 +). Then the Alice's profit is 𝑝−𝑓 +. + +Thus, we got a solution that works in 𝑂(𝑛2) +. In order to speed up this solution, we have to calculate the values 𝑓 + and 𝑝 + faster than 𝑂(𝑛) +. We can do it as follows: while iterating over the value of 𝑖 +, let's store "free" items in the ordered set, and when the size of this set becomes larger than 𝑘 +, remove the most expensive element from it; and the value of 𝑝 + can be calculated using prefix sums (over the values max(0,𝑏𝑖−𝑎𝑖) +) or maintaining a variable (and update it when moving to the next value of 𝑖 +). \ No newline at end of file diff --git a/src/codeforces/set1/set19/set196/set1969/d/solution.go b/src/codeforces/set1/set19/set196/set1969/d/solution.go new file mode 100644 index 00000000..86b39881 --- /dev/null +++ b/src/codeforces/set1/set19/set196/set1969/d/solution.go @@ -0,0 +1,151 @@ +package main + +import ( + "bufio" + "bytes" + "container/heap" + "fmt" + "os" + "sort" +) + +func main() { + reader := bufio.NewReader(os.Stdin) + + tc := readNum(reader) + + var buf bytes.Buffer + + for tc > 0 { + tc-- + n, k := readTwoNums(reader) + a := readNNums(reader, n) + b := readNNums(reader, n) + res := solve(k, a, b) + buf.WriteString(fmt.Sprintf("%d\n", res)) + } + + fmt.Print(buf.String()) +} + +func readString(reader *bufio.Reader) string { + s, _ := reader.ReadString('\n') + for i := 0; i < len(s); i++ { + if s[i] == '\n' || s[i] == '\r' { + return s[:i] + } + } + return s +} + +func readInt(bytes []byte, from int, val *int) int { + i := from + sign := 1 + if bytes[i] == '-' { + sign = -1 + i++ + } + tmp := 0 + for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' { + tmp = tmp*10 + int(bytes[i]-'0') + i++ + } + *val = tmp * sign + return i +} + +func readNum(reader *bufio.Reader) (a int) { + bs, _ := reader.ReadBytes('\n') + readInt(bs, 0, &a) + return +} + +func readTwoNums(reader *bufio.Reader) (a int, b int) { + res := readNNums(reader, 2) + a, b = res[0], res[1] + return +} + +func readThreeNums(reader *bufio.Reader) (a int, b int, c int) { + res := readNNums(reader, 3) + a, b, c = res[0], res[1], res[2] + return +} + +func readNNums(reader *bufio.Reader, n int) []int { + res := make([]int, n) + x := 0 + bs, _ := reader.ReadBytes('\n') + for i := 0; i < n; i++ { + for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' { + x++ + } + x = readInt(bs, x, &res[i]) + } + return res +} + +func solve(k int, a []int, b []int) int { + n := len(a) + arr := make([]Pair, n) + var profit int + for i := 0; i < n; i++ { + arr[i] = Pair{a[i], b[i]} + profit += max(b[i]-a[i], 0) + } + + sort.Slice(arr, func(i, j int) bool { + return arr[i].second > arr[j].second + }) + + var best int + + if k == 0 { + best = profit + } + + var f int + + pq := make(IntHeap, 0, n) + + for _, cur := range arr { + profit -= max(0, cur.second-cur.first) + heap.Push(&pq, cur.first) + f += cur.first + if pq.Len() > k { + f -= heap.Pop(&pq).(int) + } + if pq.Len() == k { + best = max(profit-f, best) + } + } + + return best + +} + +type Pair struct { + first int + second int +} + +// An IntHeap is a min-heap of ints. +type IntHeap []int + +func (h IntHeap) Len() int { return len(h) } +func (h IntHeap) Less(i, j int) bool { return h[i] > h[j] } +func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } + +func (h *IntHeap) Push(x interface{}) { + // Push and Pop use pointer receivers because they modify the slice's length, + // not just its contents. + *h = append(*h, x.(int)) +} + +func (h *IntHeap) Pop() interface{} { + old := *h + n := len(old) + x := old[n-1] + *h = old[0 : n-1] + return x +} diff --git a/src/codeforces/set1/set19/set196/set1969/d/solution_test.go b/src/codeforces/set1/set19/set196/set1969/d/solution_test.go new file mode 100644 index 00000000..78b82ec5 --- /dev/null +++ b/src/codeforces/set1/set19/set196/set1969/d/solution_test.go @@ -0,0 +1,44 @@ +package main + +import "testing" + +func runSample(t *testing.T, k int, a []int, b []int, expect int) { + res := solve(k, a, b) + + if res != expect { + t.Fatalf("Sample expect %d, but got %d", expect, res) + } +} + +func TestSample1(t *testing.T) { + k := 0 + a := []int{2, 1} + b := []int{1, 2} + expect := 1 + runSample(t, k, a, b, expect) +} + +func TestSample2(t *testing.T) { + k := 1 + a := []int{1, 2, 1, 4} + b := []int{3, 3, 2, 3} + expect := 1 + runSample(t, k, a, b, expect) +} + +func TestSample3(t *testing.T) { + k := 2 + a := []int{2, 1, 1, 1} + b := []int{4, 2, 3, 2} + expect := 0 + runSample(t, k, a, b, expect) +} + +func TestSample4(t *testing.T) { + k := 2 + a := []int{1, 3, 4, 9, 1, 3} + b := []int{7, 6, 8, 10, 6, 8} + // 不选择[9, 10]的时候,可以获得最大的收益7 + expect := 7 + runSample(t, k, a, b, expect) +} diff --git a/src/codeforces/set1/set19/set197/set1974/e/problem.md b/src/codeforces/set1/set19/set197/set1974/e/problem.md new file mode 100644 index 00000000..3edc6f29 --- /dev/null +++ b/src/codeforces/set1/set19/set197/set1974/e/problem.md @@ -0,0 +1,57 @@ +Being a physicist, Charlie likes to plan his life in simple and precise terms. + +For the next 𝑚 + months, starting with no money, Charlie will work hard and earn 𝑥 + pounds per month. For the 𝑖 +-th month (1≤𝑖≤𝑚) +, there'll be a single opportunity of paying cost 𝑐𝑖 + pounds to obtain happiness ℎ𝑖 +. + +Borrowing is not allowed. Money earned in the 𝑖 +-th month can only be spent in a later 𝑗 +-th month (𝑗>𝑖 +). + +Since physicists don't code, help Charlie find the maximum obtainable sum of happiness. + +Input +The first line of input contains a single integer 𝑡 + (1≤𝑡≤1000 +) — the number of test cases. + +The first line of each test case contains two integers, 𝑚 + and 𝑥 + (1≤𝑚≤50 +, 1≤𝑥≤108 +) — the total number of months and the monthly salary. + +The 𝑖 +-th of the following 𝑚 + lines contains two integers, 𝑐𝑖 + and ℎ𝑖 + (0≤𝑐𝑖≤108 +, 1≤ℎ𝑖≤103 +) — the cost and happiness on offer for the 𝑖 +-th month. Note that some happiness may be free (𝑐𝑖=0 + for some 𝑖 +'s). + +It is guaranteed that the sum of ∑𝑖ℎ𝑖 + over all test cases does not exceed 105 +. + +### ideas +1. 一个想法是,假设要在第i个月购买,那么alice至少要有c[i]的money +2. dp[i][j]表示在第i天时,剩余j的钱时,所购买的最大happiness +3. dp[i][j- c[i] + x] = dp[i-1][j] + h[i] +4. 但是j的范围太大了,所以这里换成alice有几个月的工资在手 +5. dp[i][j + 1] = dp[i-1][k] + h[i] 如果 (j - k) * x >= c[i] +6. +1是因为它这个月后有多了一次工资 +7. 这里出现一个问题,就是(j - k) * x - c[i]这个东西不一定整除x +8. 考虑一个例子, 比如 x = 3 +9. [0, ?], 【1, 4], [5, 4] +10. 在第一个月后获得3元钱, 购买了4,剩余2元钱, 再挣到3月钱, 剩余5元 +11. 然后第二个月可以购买4,总共8 +12. 但是 dp[1][j?]这个j不存在 +13. dp[i][x] 后面用个map来表示? \ No newline at end of file diff --git a/src/codeforces/set1/set19/set197/set1974/e/solution.go b/src/codeforces/set1/set19/set197/set1974/e/solution.go new file mode 100644 index 00000000..876a9465 --- /dev/null +++ b/src/codeforces/set1/set19/set197/set1974/e/solution.go @@ -0,0 +1,130 @@ +package main + +import ( + "bufio" + "bytes" + "fmt" + "os" +) + +func main() { + reader := bufio.NewReader(os.Stdin) + + tc := readNum(reader) + + var buf bytes.Buffer + + for tc > 0 { + tc-- + n, x := readTwoNums(reader) + records := make([][]int, n) + for i := 0; i < n; i++ { + records[i] = readNNums(reader, 2) + } + res := solve(x, records) + + buf.WriteString(fmt.Sprintf("%d\n", res)) + } + + fmt.Print(buf.String()) +} + +func readString(reader *bufio.Reader) string { + s, _ := reader.ReadString('\n') + for i := 0; i < len(s); i++ { + if s[i] == '\n' || s[i] == '\r' { + return s[:i] + } + } + return s +} + +func readInt(bytes []byte, from int, val *int) int { + i := from + sign := 1 + if bytes[i] == '-' { + sign = -1 + i++ + } + tmp := 0 + for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' { + tmp = tmp*10 + int(bytes[i]-'0') + i++ + } + *val = tmp * sign + return i +} + +func readNum(reader *bufio.Reader) (a int) { + bs, _ := reader.ReadBytes('\n') + readInt(bs, 0, &a) + return +} + +func readTwoNums(reader *bufio.Reader) (a int, b int) { + res := readNNums(reader, 2) + a, b = res[0], res[1] + return +} + +func readThreeNums(reader *bufio.Reader) (a int, b int, c int) { + res := readNNums(reader, 3) + a, b, c = res[0], res[1], res[2] + return +} + +func readNNums(reader *bufio.Reader, n int) []int { + res := make([]int, n) + x := 0 + bs, _ := reader.ReadBytes('\n') + for i := 0; i < n; i++ { + for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' { + x++ + } + x = readInt(bs, x, &res[i]) + } + return res +} + +const inf = 1 << 50 + +func solve(x int, records [][]int) int { + // m := len(records) + // dp[i] 表示alice手头有 + // 这个算法逻辑上是成立的 + // 但是它的复杂性过高 + // 是因为每个节点,相当于存储了用或者不用的信息 + // 如果要获得h的happiness最少需要多少钱? + // dp[i][j] = dp[i-1][j-h[i]] + c[i] 如果 dp[i][j] <= (i+1) * x + // + var sh int + for _, rec := range records { + sh += rec[1] + } + + dp := make([]int, sh+1) + ok := make([]bool, sh+1) + for i := 0; i <= sh; i++ { + dp[i] = inf + } + dp[0] = 0 + ok[0] = true + + for i, rec := range records { + c, h := rec[0], rec[1] + for j := sh; j >= h; j-- { + if dp[j-h]+c <= i*x && ok[j-h] { + dp[j] = min(dp[j], dp[j-h]+c) + ok[j] = true + } + } + } + + for j := sh; j > 0; j-- { + if ok[j] { + return j + } + } + + return 0 +} diff --git a/src/codeforces/set1/set19/set197/set1974/e/solution_test.go b/src/codeforces/set1/set19/set197/set1974/e/solution_test.go new file mode 100644 index 00000000..a76c8b5d --- /dev/null +++ b/src/codeforces/set1/set19/set197/set1974/e/solution_test.go @@ -0,0 +1,90 @@ +package main + +import "testing" + +func runSample(t *testing.T, x int, records [][]int, expect int) { + res := solve(x, records) + + if res != expect { + t.Fatalf("Sample expect %d, but got %d", expect, res) + } +} + +func TestSample1(t *testing.T) { + x := 10 + records := [][]int{ + {1, 5}, + } + expect := 0 + runSample(t, x, records, expect) +} + +func TestSample2(t *testing.T) { + x := 80 + records := [][]int{ + {0, 10}, + {200, 100}, + } + expect := 10 + runSample(t, x, records, expect) +} + +func TestSample3(t *testing.T) { + x := 100 + records := [][]int{ + {70, 100}, + {100, 200}, + {150, 150}, + } + expect := 200 + runSample(t, x, records, expect) +} + +func TestSample4(t *testing.T) { + x := 8 + records := [][]int{ + {3, 1}, + {5, 3}, + {3, 4}, + {1, 5}, + {5, 3}, + } + expect := 15 + runSample(t, x, records, expect) +} + +func TestSample5(t *testing.T) { + x := 5 + records := [][]int{ + {1, 5}, + {2, 1}, + } + expect := 1 + runSample(t, x, records, expect) +} + +func TestSample6(t *testing.T) { + x := 3 + records := [][]int{ + {2, 5}, + {2, 4}, + {4, 1}, + {5, 1}, + {3, 4}, + } + expect := 9 + runSample(t, x, records, expect) +} + +func TestSample7(t *testing.T) { + x := 2 + records := [][]int{ + {2, 1}, + {1, 2}, + {3, 5}, + {3, 2}, + {3, 2}, + } + expect := 9 + runSample(t, x, records, expect) +} diff --git a/src/codeforces/set1/set19/set197/set1974/f/problem.md b/src/codeforces/set1/set19/set197/set1974/f/problem.md new file mode 100644 index 00000000..e44b6b1b --- /dev/null +++ b/src/codeforces/set1/set19/set197/set1974/f/problem.md @@ -0,0 +1,58 @@ +Alice and Bob were playing a game again. They have a grid of size 𝑎×𝑏 + (1≤𝑎,𝑏≤109 +), on which there are 𝑛 + chips, with at most one chip in each cell. The cell at the intersection of the 𝑥 +-th row and the 𝑦 +-th column has coordinates (𝑥,𝑦) +. + +Alice made the first move, and the players took turns. On each move, a player could cut several (but not all) rows or columns from the beginning or end of the remaining grid and earn a point for each chip that was on the cut part of the grid. Each move can be described by the character 'U', 'D', 'L', or 'R' and an integer 𝑘 +: + +If the character is 'U', then the first 𝑘 + remaining rows will be cut; +If the character is 'D', then the last 𝑘 + remaining rows will be cut; +If the character is 'L', then the first 𝑘 + remaining columns will be cut; +If the character is 'R', then the last 𝑘 + remaining columns will be cut. +Based on the initial state of the grid and the players' moves, determine the number of points earned by Alice and Bob, respectively. + +Input +The first line contains a single integer 𝑡 + (1≤𝑡≤104 +) — the number of test cases. + +The first line of each test case contains four integers 𝑎 +, 𝑏 +, 𝑛 +, and 𝑚 + (2≤𝑎,𝑏≤109 +, 1≤𝑛,𝑚≤2⋅105 +) — the dimensions of the grid, the number of chips, and the number of moves. + +Each of the next 𝑛 + lines contain two integers 𝑥𝑖 + and 𝑦𝑖 + (1≤𝑥𝑖≤𝑎 +, 1≤𝑦𝑖≤𝑏 +) — the coordinates of the chips. All pairs of coordinates are distinct. + +Each of the next 𝑚 + lines contain a character 𝑐𝑗 + and an integer 𝑘𝑗 + — the description of the 𝑗 +-th move. It is guaranteed that 𝑘 + is less than the number of rows/columns in the current grid. In other words, a player cannot cut the entire remaining grid on their move. + +It is guaranteed that the sum of the values of 𝑛 + across all test cases in the test does not exceed 2⋅105 +. It is guaranteed that the sum of the values of 𝑚 + across all test cases in the test does not exceed 2⋅105 +. + +### ideas +1. 通过模拟是否可行? +2. 好像是可以的,问题就是每步cut的时候,快速的找到哪些clip需要被移除掉 +3. 在4个方向分别维护一个优先队列,比如在cut 上部时,使用top的队列 \ No newline at end of file diff --git a/src/codeforces/set1/set19/set197/set1974/f/solution.go b/src/codeforces/set1/set19/set197/set1974/f/solution.go new file mode 100644 index 00000000..45c4e9d9 --- /dev/null +++ b/src/codeforces/set1/set19/set197/set1974/f/solution.go @@ -0,0 +1,245 @@ +package main + +import ( + "bufio" + "bytes" + "container/heap" + "fmt" + "os" +) + +func main() { + reader := bufio.NewReader(os.Stdin) + + tc := readNum(reader) + + var buf bytes.Buffer + + for tc > 0 { + tc-- + nums := readNNums(reader, 4) + a, b, n, m := nums[0], nums[1], nums[2], nums[3] + clips := make([][]int, n) + for i := 0; i < n; i++ { + clips[i] = readNNums(reader, 2) + } + ops := make([]string, m) + for i := 0; i < m; i++ { + ops[i] = readString(reader) + } + res := solve(a, b, clips, ops) + buf.WriteString(fmt.Sprintf("%d %d\n", res[0], res[1])) + } + + fmt.Print(buf.String()) +} +func readString(reader *bufio.Reader) string { + s, _ := reader.ReadString('\n') + for i := 0; i < len(s); i++ { + if s[i] == '\n' || s[i] == '\r' { + return s[:i] + } + } + return s +} + +func readInt(bytes []byte, from int, val *int) int { + i := from + sign := 1 + if bytes[i] == '-' { + sign = -1 + i++ + } + tmp := 0 + for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' { + tmp = tmp*10 + int(bytes[i]-'0') + i++ + } + *val = tmp * sign + return i +} + +func readNum(reader *bufio.Reader) (a int) { + bs, _ := reader.ReadBytes('\n') + readInt(bs, 0, &a) + return +} + +func readTwoNums(reader *bufio.Reader) (a int, b int) { + res := readNNums(reader, 2) + a, b = res[0], res[1] + return +} + +func readThreeNums(reader *bufio.Reader) (a int, b int, c int) { + res := readNNums(reader, 3) + a, b, c = res[0], res[1], res[2] + return +} + +func readNNums(reader *bufio.Reader, n int) []int { + res := make([]int, n) + x := 0 + bs, _ := reader.ReadBytes('\n') + for i := 0; i < n; i++ { + for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' { + x++ + } + x = readInt(bs, x, &res[i]) + } + return res +} + +const inf = 1 << 60 + +func solve(a, b int, clips [][]int, operations []string) []int { + top := NewStore(clips, func(clip []int) int { + return clip[0] + }) + + bot := NewStore(clips, func(clip []int) int { + return -clip[0] + }) + + lft := NewStore(clips, func(clip []int) int { + return clip[1] + }) + + rgt := NewStore(clips, func(clip []int) int { + return -clip[1] + }) + + stores := []*Store{top, bot, lft, rgt} + ids := map[byte]int{'U': 0, 'D': 1, 'L': 2, 'R': 3} + + rect := []int{1, 1, a, b} + + play := func(s string) int { + cmd := s[0] + var k int + readInt([]byte(s), 2, &k) + + if cmd == 'U' { + rect[0] += k + } else if cmd == 'D' { + rect[2] -= k + } else if cmd == 'L' { + rect[1] += k + } else { + rect[3] -= k + } + + i := ids[cmd] + + var cnt int + + for !stores[i].IsEmpty() { + first := stores[i].First() + clip := clips[first.id] + + if clip[0] >= rect[0] && clip[0] <= rect[2] && clip[1] >= rect[1] && clip[1] <= rect[3] { + // in the left area + break + } + cnt++ + + for j := 0; j < 4; j++ { + stores[j].Remove(first.id) + } + } + + return cnt + } + + res := make([]int, 2) + + for i, cur := range operations { + res[i&1] += play(cur) + } + + return res +} + +type Item struct { + id int + priority int + index int +} + +type PQ []*Item + +func (pq PQ) Len() int { + return len(pq) +} + +func (pq PQ) Less(i, j int) bool { + return pq[i].priority < pq[j].priority +} + +func (pq PQ) Swap(i, j int) { + pq[i], pq[j] = pq[j], pq[i] + pq[i].index = i + pq[j].index = j +} + +func (pq *PQ) Push(x any) { + it := x.(*Item) + it.index = len(*pq) + *pq = append(*pq, it) +} + +func (pq *PQ) Pop() any { + old := *pq + n := len(old) + res := old[n-1] + res.index = -1 + *pq = old[:n-1] + return res +} + +func (pq *PQ) update(it *Item, v int) { + it.priority = v + heap.Fix(pq, it.index) +} + +func (pq *PQ) remove(it *Item) { + pq.update(it, -inf) + heap.Pop(pq) +} + +type Store struct { + arr []*Item + pq *PQ +} + +func NewStore(clips [][]int, pf func([]int) int) *Store { + n := len(clips) + + arr := make([]*Item, n) + pq := make(PQ, n) + + for i := 0; i < n; i++ { + it := new(Item) + it.id = i + it.index = i + it.priority = pf(clips[i]) + arr[i] = it + pq[i] = it + } + + heap.Init(&pq) + + return &Store{arr, &pq} +} + +func (store *Store) IsEmpty() bool { + return store.pq.Len() == 0 +} + +func (store *Store) First() *Item { + return (*(store.pq))[0] +} + +func (store *Store) Remove(id int) { + store.pq.remove(store.arr[id]) +} diff --git a/src/codeforces/set1/set19/set197/set1974/f/solution_test.go b/src/codeforces/set1/set19/set197/set1974/f/solution_test.go new file mode 100644 index 00000000..884a5027 --- /dev/null +++ b/src/codeforces/set1/set19/set197/set1974/f/solution_test.go @@ -0,0 +1,60 @@ +package main + +import ( + "reflect" + "testing" +) + +func runSample(t *testing.T, a, b int, clips [][]int, operations []string, expect []int) { + res := solve(a, b, clips, operations) + + if !reflect.DeepEqual(res, expect) { + t.Fatalf("Sample expect %v, but got %v", expect, res) + } +} + +func TestSample1(t *testing.T) { + a, b := 4, 4 + clips := [][]int{ + {4, 1}, + {3, 3}, + {2, 4}, + } + ops := []string{ + "D 2", + "R 1", + } + expect := []int{2, 1} + runSample(t, a, b, clips, ops, expect) +} + +func TestSample2(t *testing.T) { + a, b := 4, 4 + clips := [][]int{ + {4, 1}, + {3, 2}, + {2, 3}, + } + ops := []string{ + "D 1", + "L 1", + "U 2", + } + expect := []int{2, 0} + runSample(t, a, b, clips, ops, expect) +} + +func TestSample3(t *testing.T) { + a, b := 3, 5 + clips := [][]int{ + {1, 3}, + {2, 2}, + {3, 3}, + } + ops := []string{ + "R 2", + "R 2", + } + expect := []int{0, 3} + runSample(t, a, b, clips, ops, expect) +}