1
+ use std:: collections:: { BTreeSet , HashMap } ;
2
+ use std:: cmp:: max;
3
+
4
+ struct SegmentTree {
5
+ lch : Option < Box < SegmentTree > > ,
6
+ rch : Option < Box < SegmentTree > > ,
7
+ val : i32 ,
8
+ delta : i32 ,
9
+ }
10
+
11
+ impl SegmentTree {
12
+ fn new ( n : usize ) -> Self {
13
+ * Self :: cons ( 1 , n) . unwrap ( )
14
+ }
15
+ fn new_leaf ( ) -> Option < Box < SegmentTree > > {
16
+ Some ( Box :: new ( SegmentTree {
17
+ lch : None ,
18
+ rch : None ,
19
+ val : 0 ,
20
+ delta : 0 ,
21
+ } ) )
22
+ }
23
+ fn cons ( l : usize , r : usize ) -> Option < Box < SegmentTree > > {
24
+ if l == r {
25
+ return Self :: new_leaf ( ) ;
26
+ }
27
+ let m = ( l+r) /2 ;
28
+ Some ( Box :: new ( SegmentTree {
29
+ lch : Self :: cons ( l, m) ,
30
+ rch : Self :: cons ( m+1 , r) ,
31
+ val : 0 ,
32
+ delta : 0 ,
33
+ } ) )
34
+ }
35
+ fn search ( & self , l : usize , r : usize , left : usize , right : usize ) -> i32 {
36
+ if l == left && r == right {
37
+ if self . delta > 0 {
38
+ return self . delta ;
39
+ }
40
+ return self . val ;
41
+ }
42
+ if self . delta > 0 {
43
+ return self . delta ;
44
+ }
45
+ let m = ( l+r) /2 ;
46
+ if right <= m {
47
+ self . lch . as_ref ( ) . unwrap ( ) . search ( l, m, left, right)
48
+ } else if left > m {
49
+ self . rch . as_ref ( ) . unwrap ( ) . search ( m+1 , r, left, right)
50
+ } else {
51
+ max (
52
+ self . lch . as_ref ( ) . unwrap ( ) . search ( l, m, left, m) ,
53
+ self . rch . as_ref ( ) . unwrap ( ) . search ( m+1 , r, m+1 , right) ,
54
+ )
55
+ }
56
+ }
57
+ fn update ( & mut self , l : usize , r : usize , left : usize , right : usize , h : i32 ) -> i32 {
58
+ if l == left && r == right {
59
+ if l == r {
60
+ self . val = h;
61
+ } else {
62
+ self . delta = h;
63
+ }
64
+ return h;
65
+ }
66
+ let m = ( l+r) /2 ;
67
+ if self . delta > 0 {
68
+ self . lch . as_mut ( ) . unwrap ( ) . update ( l, m, l, m, self . delta ) ;
69
+ self . rch . as_mut ( ) . unwrap ( ) . update ( m+1 , r, m+1 , r, self . delta ) ;
70
+ self . delta = 0 ;
71
+ }
72
+ if right <= m {
73
+ let lmax = self . lch . as_mut ( ) . unwrap ( ) . update ( l, m, left, right, h) ;
74
+ self . val = self . val . max ( lmax) ;
75
+ } else if left > m {
76
+ let rmax = self . rch . as_mut ( ) . unwrap ( ) . update ( m+1 , r, left, right, h) ;
77
+ self . val = self . val . max ( rmax) ;
78
+ } else {
79
+ let lmax = self . lch . as_mut ( ) . unwrap ( ) . update ( l, m, left, m, h) ;
80
+ let rmax = self . rch . as_mut ( ) . unwrap ( ) . update ( m+1 , r, m+1 , right, h) ;
81
+ self . val = max ( lmax, rmax) ;
82
+ }
83
+ self . val
84
+ }
85
+ }
86
+
87
+ impl Solution {
88
+ pub fn falling_squares ( positions : Vec < Vec < i32 > > ) -> Vec < i32 > {
89
+ let mut bs = BTreeSet :: new ( ) ;
90
+ for pos in & positions {
91
+ let ( x, l) = ( pos[ 0 ] , pos[ 1 ] ) ;
92
+ bs. insert ( x) ;
93
+ bs. insert ( x+l-1 ) ;
94
+ }
95
+ let mut hash = HashMap :: new ( ) ;
96
+ for ( i, & v) in bs. iter ( ) . enumerate ( ) {
97
+ hash. insert ( v, i+1 ) ;
98
+ }
99
+ let n = bs. len ( ) ;
100
+ let mut sgt = SegmentTree :: new ( n) ;
101
+ positions. into_iter ( ) . map ( |pos| {
102
+ let ( x, l) = ( pos[ 0 ] , pos[ 1 ] ) ;
103
+ let mx = * hash. get ( & x) . unwrap ( ) ;
104
+ let my = * hash. get ( & ( x+l-1 ) ) . unwrap ( ) ;
105
+ let t = sgt. search ( 1 , n, mx, my) ;
106
+ let v = sgt. update ( 1 , n, mx, my, l+t) ;
107
+ v
108
+ } ) . collect ( )
109
+ }
110
+ }
111
+
112
+ struct Solution ;
113
+
114
+ #[ cfg( test) ]
115
+ mod tests {
116
+ use super :: Solution ;
117
+
118
+ #[ test]
119
+ fn test_falling_squares ( ) {
120
+ let test_cases = vec ! [
121
+ ( vec![
122
+ vec![ 9 , 7 ] , vec![ 1 , 9 ] , vec![ 3 , 1 ] , vec![ 1 , 1 ] , vec![ 2 , 2 ] , vec![ 100 , 15 ] , vec![ 15 , 13 ] ,
123
+ ] , vec![ 7 , 16 , 17 , 17 , 19 , 19 , 20 ] ) ,
124
+ ( vec![
125
+ vec![ 100 , 100 ] , vec![ 200 , 100 ] , vec![ 199 , 2 ] ,
126
+ ] , vec![ 100 , 100 , 102 ] ) ,
127
+ ( vec![
128
+ vec![ 1 , 2 ] , vec![ 2 , 3 ] , vec![ 6 , 1 ] ,
129
+ ] , vec![ 2 , 5 , 5 ] ) ,
130
+ ] ;
131
+ for ( positions, expect) in test_cases {
132
+ assert_eq ! ( Solution :: falling_squares( positions. clone( ) ) , expect, "positions: {:?}" , positions) ;
133
+ }
134
+ }
135
+ }
0 commit comments