699.falling-squares.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. type node struct {
  2. l int
  3. r int
  4. left *node
  5. right *node
  6. max int
  7. tag int // Lazy
  8. }
  9. var tree []node
  10. var tid int
  11. func (root *node) buildTree(l, r int) {
  12. root.l = l
  13. root.r = r
  14. if l == r {
  15. return
  16. }
  17. tid++
  18. root.left = &tree[tid]
  19. tid++
  20. root.right = &tree[tid]
  21. root.left.buildTree(l, (l+r)/2)
  22. root.right.buildTree((l+r)/2+1, r)
  23. }
  24. func (root *node) update(i, j, val int) {
  25. if root.l == i && root.r == j {
  26. root.tag = val
  27. return
  28. }
  29. root.max = maxInt(root.max, val)
  30. if m := (root.l + root.r) / 2; j <= m {
  31. root.left.update(i, j, val) // Update left tree
  32. } else if m+1 <= i {
  33. root.right.update(i, j, val) // Right tree
  34. } else {
  35. root.left.update(i, m, val) // Split into 2 parts
  36. root.right.update(m+1, j, val)
  37. }
  38. }
  39. func (root *node) query(i, j int) int {
  40. if root.l == i && root.r == j {
  41. if root.tag != 0 {
  42. return root.tag
  43. }
  44. return root.max
  45. }
  46. m := (root.l + root.r) / 2
  47. if root.tag != 0 {
  48. root.max = root.tag // PushDown method
  49. root.left.update(root.l, m, root.tag)
  50. root.right.update(m+1, root.r, root.tag)
  51. }
  52. root.tag = 0 // Finished update
  53. if j <= m {
  54. return root.left.query(i, j)
  55. } else if m+1 <= i {
  56. return root.right.query(i, j)
  57. } else {
  58. return maxInt(root.left.query(i, m), root.right.query(m+1, j))
  59. }
  60. }
  61. func fallingSquares(positions [][]int) []int {
  62. pts := make([]int, 0)
  63. m := make(map[int]int)
  64. for _, pos := range positions {
  65. beg, end := pos[0], pos[0]+pos[1]-1
  66. if _, ok := m[beg]; !ok {
  67. m[beg] = 0
  68. pts = append(pts, beg)
  69. }
  70. if _, ok := m[end]; !ok {
  71. m[end] = 0
  72. pts = append(pts, end)
  73. }
  74. }
  75. sort.Ints(pts)
  76. for i := range pts {
  77. m[pts[i]] = i + 1
  78. } // Discretization
  79. n := len(pts)
  80. tree = make([]node, 2*n)
  81. tid = 0
  82. root := &tree[0]
  83. root.buildTree(1, n)
  84. res := make([]int, len(positions))
  85. for idx, pos := range positions {
  86. i, j := m[pos[0]], m[pos[0]+pos[1]-1]
  87. max := root.query(i, j)
  88. root.update(i, j, max+pos[1])
  89. res[idx] = root.query(1, n)
  90. }
  91. return res
  92. }
  93. func maxInt(x, y int) int {
  94. if x < y {
  95. return y
  96. }
  97. return x
  98. }