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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
class Seg:
def __init__(self,n):
self.L = n.bit_length()
self.N = N = 1<<self.L
self.t = [0]*N*2
self.f = [0]*N*2
self.sz = [0]*N*2
def apply(self,o,x):
self.t[o] += x
self.f[o] += x
def build(self,A):
for i in range(len(A)-1):
self.sz[self.N+i] = A[i+1]-A[i]
for o in range(self.N-1,0,-1):
self.pull(o)
def pull(self,o):
t,sz = self.t,self.sz
t[o] = min(t[o*2],t[o*2+1])
sz[o] = sz[o*2]*(t[o]==t[o*2])+sz[o*2+1]*(t[o]==t[o*2+1])
def push(self,o):
if self.f[o] != self.f[0]:
self.apply(o*2,self.f[o])
self.apply(o*2+1,self.f[o])
self.f[o] = self.f[0]
def modify(self,a,b,x):
a,b = a+self.N-1,b+self.N+1
for i in range(self.L,0,-1):
self.push(a>>i)
self.push(b>>i)
while a^b^1:
if not a&1: self.apply(a^1,x)
if b&1: self.apply(b^1,x)
a,b = a>>1,b>>1
self.pull(a)
self.pull(b)
while a>>1:
a >>= 1
self.pull(a)
class Solution:
def separateSquares(self, squares: List[List[int]]) -> float:
V = sorted({a for x,y,l in squares for a in [x,x+l]})
mp = {a:i for i,a in enumerate(V)}
d = defaultdict(list)
for x,y,l in squares:
x1,x2 = mp[x],mp[x+l]-1
d[y].append((x1,x2,1))
d[y+l].append((x1,x2,-1))
s = 0
seg = Seg(len(V)-1)
seg.build(V)
for y1,y2 in pairwise(sorted(d)):
for x1,x2,flag in d[y1]:
seg.modify(x1,x2,flag)
w = V[-1]-V[0]-(seg.sz[1] if seg.t[1]==0 else 0)
s += w*(y2-y1)
t = 0
seg = Seg(len(V)-1)
seg.build(V)
for y1,y2 in pairwise(sorted(d)):
for x1,x2,flag in d[y1]:
seg.modify(x1,x2,flag)
w = V[-1]-V[0]-(seg.sz[1] if seg.t[1]==0 else 0)
t += w*(y2-y1)
if t*2>=s:
return y2-(t*2-s)/2/w
|