@@ -79,14 +79,92 @@ private long mergeIntervals(List<int[]> active) {
7979 }
8080
8181
82+ /**
83+ * https://leetcode.com/problems/rectangle-area-ii/solution/
84+ */
85+ public int rectangleArea2 (int [][] rectangles ) {
86+ int OPEN = 1 , CLOSE = -1 ;
87+ int [][] events = new int [rectangles .length * 2 ][];
88+ Set <Integer > Xvals = new HashSet ();
89+ int t = 0 ;
90+ for (int [] rec : rectangles ) {
91+ events [t ++] = new int []{rec [1 ], OPEN , rec [0 ], rec [2 ]};
92+ events [t ++] = new int []{rec [3 ], CLOSE , rec [0 ], rec [2 ]};
93+ Xvals .add (rec [0 ]);
94+ Xvals .add (rec [2 ]);
95+ }
8296
97+ Arrays .sort (events , (a , b ) -> Integer .compare (a [0 ], b [0 ]));
8398
99+ Integer [] X = Xvals .toArray (new Integer [0 ]);
100+ Arrays .sort (X );
101+ Map <Integer , Integer > Xi = new HashMap ();
102+ for (int i = 0 ; i < X .length ; ++i )
103+ Xi .put (X [i ], i );
84104
105+ Node active = new Node (0 , X .length - 1 , X );
106+ long ans = 0 ;
107+ long cur_x_sum = 0 ;
108+ int cur_y = events [0 ][0 ];
85109
110+ for (int [] event : events ) {
111+ int y = event [0 ], typ = event [1 ], x1 = event [2 ], x2 = event [3 ];
112+ ans += cur_x_sum * (y - cur_y );
113+ cur_x_sum = active .update (Xi .get (x1 ), Xi .get (x2 ), typ );
114+ cur_y = y ;
86115
87-
116+ }
88117
118+ ans %= 1_000_000_007 ;
119+ return (int ) ans ;
120+ }
89121
90122
123+ class Node {
124+ int start , end ;
125+ Integer [] X ;
126+ Node left , right ;
127+ int count ;
128+ long total ;
129+
130+ public Node (int start , int end , Integer [] X ) {
131+ this .start = start ;
132+ this .end = end ;
133+ this .X = X ;
134+ left = null ;
135+ right = null ;
136+ count = 0 ;
137+ total = 0 ;
138+ }
139+
140+ public int getRangeMid () {
141+ return start + (end - start ) / 2 ;
142+ }
143+
144+ public Node getLeft () {
145+ if (left == null ) left = new Node (start , getRangeMid (), X );
146+ return left ;
147+ }
148+
149+ public Node getRight () {
150+ if (right == null ) right = new Node (getRangeMid (), end , X );
151+ return right ;
152+ }
153+
154+ public long update (int i , int j , int val ) {
155+ if (i >= j ) return 0 ;
156+ if (start == i && end == j ) {
157+ count += val ;
158+ } else {
159+ getLeft ().update (i , Math .min (getRangeMid (), j ), val );
160+ getRight ().update (Math .max (getRangeMid (), i ), j , val );
161+ }
162+
163+ if (count > 0 ) total = X [end ] - X [start ];
164+ else total = getLeft ().total + getRight ().total ;
165+
166+ return total ;
167+ }
168+ }
91169
92170}
0 commit comments