Problem:


Score: 600 points

Problem Statement

There is a grass field that stretches infinitely.

In this field, there is a negligibly small cow. Let (x, y) denote the point that is x\ \mathrm{cm} south and y\ \mathrm{cm} east of the point where the cow stands now. The cow itself is standing at (0, 0).

There are also N north-south lines and M east-west lines drawn on the field. The i-th north-south line is the segment connecting the points (A_i, C_i) and (B_i, C_i), and the j-th east-west line is the segment connecting the points (D_j, E_j) and (D_j, F_j).

What is the area of the region the cow can reach when it can move around as long as it does not cross the segments (including the endpoints)? If this area is infinite, print INF instead.

Constraints

All values in input are integers between -10^9 and 10^9  (inclusive).

1 \leq N, M \leq 1000

A_i < B_i\ (1 \leq i \leq N)

E_j < F_j\ (1 \leq j \leq M)

The point (0, 0) does not lie on any of the given segments.

Input

Input is given from Standard Input in the following format:

N M
A_1 B_1 C_1
:
A_N B_N C_N
D_1 E_1 F_1
:
D_M E_M F_M

Output

If the area of the region the cow can reach is infinite, print INF; otherwise, print an integer representing the area in \mathrm{cm^2}.

(Under the constraints, it can be proved that the area of the region is always an integer if it is not infinite.)

Sample Input 1

5 6
1 2 0
0 1 1
0 2 2
-3 4 -1
-2 6 3
1 0 1
0 1 2
2 0 2
-1 -4 5
3 -2 4
1 2 4

Sample Output 1

13

The area of the region the cow can reach is 13\ \mathrm{cm^2}.

Sample Input 2

6 1
-3 -1 -2
-3 -1 1
-2 -1 2
1 4 -2
1 4 -1
1 4 1
3 1 4

Sample Output 2

INF

The area of the region the cow can reach is infinite.



Sample input:
5 6
1 2 0
0 1 1
0 2 2
-3 4 -1
-2 6 3
1 0 1
0 1 2
2 0 2
-1 -4 5
3 -2 4
1 2 4


Sample output:
13

Submission status: Time Limit Exceeded

Solution code:
import sys
from collections import deque
import io, os
input = io.BytesIO(os.read(0,os.fstat(0).st_size)).readline

N,M=map(int,input().split())
TATE=[tuple(map(int,input().split())) for i in range(N)]
YOKO=[tuple(map(int,input().split())) for i in range(M)]


T=[-1<<63,0,1<<63]
Y=[-1<<63,0,1<<63]

for a,b,c in TATE:
    T.append(a)
    T.append(b)
    Y.append(c)

for d,e,f in YOKO:
    T.append(d)
    Y.append(e)
    Y.append(f)

T=sorted(set(T))
Y=sorted(set(Y))

BT=[T[0]]
BY=[Y[0]]

for i in range(1,len(T)):
    BT.append(T[i]-T[i-1])
    BT.append(T[i])

for i in range(1,len(Y)):
    BY.append(Y[i]-Y[i-1])
    BY.append(Y[i])

TDICT=dict()
YDICT=dict()

LBT=len(BT)
LBY=len(BY)

for i in range(LBT):
    if i%2==0:
        TDICT[BT[i]]=i

for i in range(LBY):
    if i%2==0:
        YDICT[BY[i]]=i

MAP=[[0]*(LBY+1) for i in range(LBT+1)]

for a,b,c in TATE:
    t0=TDICT[a]
    t1=TDICT[b]
    y=YDICT[c]

    MAP[t0][y]+=1
    MAP[t0][y+1]-=1
    MAP[t1+1][y]-=1
    MAP[t1+1][y+1]+=1

for d,e,f in YOKO:
    t=TDICT[d]
    y0=YDICT[e]
    y1=YDICT[f]

    MAP[t][y0]+=1
    MAP[t+1][y0]-=1
    MAP[t][y1+1]-=1
    MAP[t+1][y1+1]+=1

for i in range(LBT):
    for j in range(1,LBY):
        MAP[i][j]+=MAP[i][j-1]

for i in range(LBY):
    for j in range(1,LBT):
        MAP[j][i]+=MAP[j-1][i]

#for m in MAP:
#    print(*m)

Q=deque()
Q.append((TDICT[0],YDICT[0]))
ANS=0

while Q:
    x,y=Q.pop()
    for z,w in [(x+1,y),(x-1,y),(x,y-1),(x,y+1)]:
        if MAP[z][w]==0:
            MAP[z][w]=1
            Q.append((z,w))
            if z%2==1 and w%2==1:
                ANS+=BT[z]*BY[w]

    if ANS>=1<<62:
        print("INF")
        sys.exit()

print(ANS)

Submission status: Time Limit Exceeded

Solution code:
import sys
from collections import deque
input = sys.stdin.readline

N,M=map(int,input().split())
TATE=[tuple(map(int,input().split())) for i in range(N)]
YOKO=[tuple(map(int,input().split())) for i in range(M)]


T=[-1<<63,0,1<<63]
Y=[-1<<63,0,1<<63]

for a,b,c in TATE:
    T.append(a)
    T.append(b)
    Y.append(c)

for d,e,f in YOKO:
    T.append(d)
    Y.append(e)
    Y.append(f)

T=sorted(set(T))
Y=sorted(set(Y))

BT=[T[0]]
BY=[Y[0]]

for i in range(1,len(T)):
    BT.append(T[i]-T[i-1])
    BT.append(T[i])

for i in range(1,len(Y)):
    BY.append(Y[i]-Y[i-1])
    BY.append(Y[i])

TDICT=dict()
YDICT=dict()

LBT=len(BT)
LBY=len(BY)

for i in range(LBT):
    if i%2==0:
        TDICT[BT[i]]=i

for i in range(LBY):
    if i%2==0:
        YDICT[BY[i]]=i

MAP=[[0]*(LBY+1) for i in range(LBT+1)]

for a,b,c in TATE:
    t0=TDICT[a]
    t1=TDICT[b]
    y=YDICT[c]

    MAP[t0][y]+=1
    MAP[t0][y+1]-=1
    MAP[t1+1][y]-=1
    MAP[t1+1][y+1]+=1

for d,e,f in YOKO:
    t=TDICT[d]
    y0=YDICT[e]
    y1=YDICT[f]

    MAP[t][y0]+=1
    MAP[t+1][y0]-=1
    MAP[t][y1+1]-=1
    MAP[t+1][y1+1]+=1

for i in range(LBT):
    for j in range(1,LBY):
        MAP[i][j]+=MAP[i][j-1]

for i in range(LBY):
    for j in range(1,LBT):
        MAP[j][i]+=MAP[j-1][i]

#for m in MAP:
#    print(*m)

Q=deque()
Q.append((TDICT[0],YDICT[0]))
ANS=0

while Q:
    x,y=Q.pop()
    for z,w in [(x+1,y),(x-1,y),(x,y-1),(x,y+1)]:
        if MAP[z][w]==0:
            MAP[z][w]=1
            Q.append((z,w))
            if z%2==1 and w%2==1:
                ANS+=BT[z]*BY[w]

    if ANS>=1<<62:
        print("INF")
        sys.exit()

print(ANS)

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.readline

N,M=map(int,input().split())
TATE=[tuple(map(int,input().split())) for i in range(N)]
YOKO=[tuple(map(int,input().split())) for i in range(M)]


T=[-1<<63,0,1<<63]
Y=[-1<<63,0,1<<63]

for a,b,c in TATE:
    T.append(a)
    T.append(b)
    Y.append(c)

for d,e,f in YOKO:
    T.append(d)
    Y.append(e)
    Y.append(f)

T=sorted(set(T))
Y=sorted(set(Y))

BT=[T[0]]
BY=[Y[0]]

for i in range(1,len(T)):
    BT.append(T[i]-T[i-1])
    BT.append(T[i])

for i in range(1,len(Y)):
    BY.append(Y[i]-Y[i-1])
    BY.append(Y[i])

TDICT=dict()
YDICT=dict()

LBT=len(BT)
LBY=len(BY)

for i in range(LBT):
    if i%2==0:
        TDICT[BT[i]]=i

for i in range(LBY):
    if i%2==0:
        YDICT[BY[i]]=i

MAP=[[0]*(LBY+1) for i in range(LBT+1)]

for a,b,c in TATE:
    t0=TDICT[a]
    t1=TDICT[b]
    y=YDICT[c]

    MAP[t0][y]+=1
    MAP[t0][y+1]-=1
    MAP[t1+1][y]-=1
    MAP[t1+1][y+1]+=1

for d,e,f in YOKO:
    t=TDICT[d]
    y0=YDICT[e]
    y1=YDICT[f]

    MAP[t][y0]+=1
    MAP[t+1][y0]-=1
    MAP[t][y1+1]-=1
    MAP[t+1][y1+1]+=1

for i in range(LBT):
    for j in range(1,LBY):
        MAP[i][j]+=MAP[i][j-1]

for i in range(LBY):
    for j in range(1,LBT):
        MAP[j][i]+=MAP[j-1][i]

#for m in MAP:
#    print(*m)

Q=[(TDICT[0],YDICT[0])]
ANS=0

while Q:
    x,y=Q.pop()
    for z,w in [(x+1,y),(x-1,y),(x,y-1),(x,y+1)]:
        if MAP[z][w]==0:
            MAP[z][w]=1
            Q.append((z,w))
            if z%2==1 and w%2==1:
                ANS+=BT[z]*BY[w]

    if ANS>=1<<62:
        print("INF")
        sys.exit()

print(ANS)

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.readline

N,M=map(int,input().split())
TATE=[tuple(map(int,input().split())) for i in range(N)]
YOKO=[tuple(map(int,input().split())) for i in range(M)]


T=[-1<<62,0,1<<62]
Y=[-1<<62,0,1<<62]

for a,b,c in TATE:
    T.append(a)
    T.append(b)
    Y.append(c)

for d,e,f in YOKO:
    T.append(d)
    Y.append(e)
    Y.append(f)

T=sorted(set(T))
Y=sorted(set(Y))

BT=[T[0]]
BY=[Y[0]]

for i in range(1,len(T)):
    BT.append(T[i]-T[i-1])
    BT.append(T[i])

for i in range(1,len(Y)):
    BY.append(Y[i]-Y[i-1])
    BY.append(Y[i])

TDICT=dict()
YDICT=dict()

for i in range(len(BT)):
    if i%2==0:
        TDICT[BT[i]]=i

for i in range(len(BY)):
    if i%2==0:
        YDICT[BY[i]]=i

MAP=[[0]*(len(BY)+1) for i in range(len(BT)+1)]

for a,b,c in TATE:
    t0=TDICT[a]
    t1=TDICT[b]
    y=YDICT[c]

    MAP[t0][y]+=1
    MAP[t0][y+1]-=1
    MAP[t1+1][y]-=1
    MAP[t1+1][y+1]+=1

for d,e,f in YOKO:
    t=TDICT[d]
    y0=YDICT[e]
    y1=YDICT[f]

    MAP[t][y0]+=1
    MAP[t+1][y0]-=1
    MAP[t][y1+1]-=1
    MAP[t+1][y1+1]+=1

for i in range(len(BT)):
    for j in range(1,len(BY)):
        MAP[i][j]+=MAP[i][j-1]

for i in range(len(BY)):
    for j in range(1,len(BT)):
        MAP[j][i]+=MAP[j-1][i]

#for m in MAP:
#    print(*m)

Q=[(TDICT[0],YDICT[0])]
ANS=0

while Q:
    x,y=Q.pop()
    for z,w in [(x+1,y),(x-1,y),(x,y-1),(x,y+1)]:
        if 0<=z<len(BT) and 0<=w<len(BY) and MAP[z][w]==0:
            MAP[z][w]=1
            Q.append((z,w))
            if z%2==1 and w%2==1:
                ANS+=BT[z]*BY[w]

    if ANS>=1<<62:
        print("INF")
        sys.exit()

print(ANS)

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.readline

N,M=map(int,input().split())
TATE=[tuple(map(int,input().split())) for i in range(N)]
YOKO=[tuple(map(int,input().split())) for i in range(M)]


T=[-1<<62,0,1<<62]
Y=[-1<<62,0,1<<62]

for a,b,c in TATE:
    T.append(a)
    T.append(b)
    Y.append(c)

for d,e,f in YOKO:
    T.append(d)
    Y.append(e)
    Y.append(f)

T=sorted(set(T))
Y=sorted(set(Y))

BT=[T[0]]
BY=[Y[0]]

for i in range(1,len(T)):
    BT.append(T[i]-T[i-1])
    BT.append(T[i])

for i in range(1,len(Y)):
    BY.append(Y[i]-Y[i-1])
    BY.append(Y[i])

TDICT=dict()
YDICT=dict()

for i in range(len(BT)):
    if i%2==0:
        TDICT[BT[i]]=i

for i in range(len(BY)):
    if i%2==0:
        YDICT[BY[i]]=i

MAP=[[0]*(len(BY)+1) for i in range(len(BT)+1)]

for a,b,c in TATE:
    t0=TDICT[a]
    t1=TDICT[b]
    y=YDICT[c]

    MAP[t0][y]+=1
    MAP[t0][y+1]-=1
    MAP[t1+1][y]-=1
    MAP[t1+1][y+1]+=1

for d,e,f in YOKO:
    t=TDICT[d]
    y0=YDICT[e]
    y1=YDICT[f]

    MAP[t][y0]+=1
    MAP[t+1][y0]-=1
    MAP[t][y1+1]-=1
    MAP[t+1][y1+1]+=1

for i in range(len(BT)):
    for j in range(1,len(BY)):
        MAP[i][j]+=MAP[i][j-1]

for i in range(len(BY)):
    for j in range(1,len(BT)):
        MAP[j][i]+=MAP[j-1][i]

#for m in MAP:
#    print(*m)

Q=[(TDICT[0],YDICT[0])]
ANS=0

while Q:
    x,y=Q.pop()
    for z,w in [(x+1,y),(x-1,y),(x,y-1),(x,y+1)]:
        if 0<=z<len(BT) and 0<=w<len(BY) and MAP[z][w]==0:
            MAP[z][w]=1
            Q.append((z,w))
            if z%2==1 and w%2==1:
                ANS+=BT[z]*BY[w]

if ANS>=1<<62:
    print("INF")
else:
    print(ANS)

Submission status: Time Limit Exceeded

Solution code:
#!/usr/bin/env python3

import sys
from queue import Queue
from pprint import pprint
sys.setrecursionlimit(300000)


def solve(N: int, M: int, A: "List[int]", B: "List[int]", C: "List[int]", D: "List[int]", E: "List[int]", F: "List[int]"):
    xs, ys = {}, {}
    xs[0] = 0
    ys[0] = 0
    for i in range(N):
        xs[A[i]] = 0
        xs[B[i]] = 0
        ys[C[i]] = 0
    for i in range(M):
        xs[D[i]] = 0
        ys[E[i]] = 0
        ys[F[i]] = 0

    sx, sy = [], []
    ox = sorted(xs.keys())
    for i, x in enumerate(ox):
        xs[x] = i
        sx.append(x)
    oy = sorted(ys.keys())
    for i, y in enumerate(oy):
        ys[y] = i
        sy.append(y)

    h, w = len(sy) * 2, len(sx) * 2
    g = [[0] * w for _ in range(h)]
    for i in range(N):
        y = ys[C[i]] * 2
        for x in range(xs[A[i]] * 2, xs[B[i]] * 2 + 1):
            g[y][x] = 1
    for i in range(M):
        x = xs[D[i]] * 2
        for y in range(ys[E[i]] * 2, ys[F[i]] * 2 + 1):
            g[y][x] = 1

    x, y = xs[0] * 2, ys[0] * 2
    g[y][x] = 2
    q = Queue()
    q.put((x, y))
    dx = [0, -1, 0, 1]
    dy = [1, 0, -1, 0]
    ret = 0
    #pprint(g)
    while not q.empty():
        x, y = q.get()
        if x % 2 and y % 2:
            xx = sx[x // 2 + 1] - sx[x // 2]
            yy = sy[y // 2 + 1] - sy[y // 2]
            ret += xx * yy
        for k in range(len(dx)):
            tx, ty = x + dx[k], y + dy[k]
            if 0 <= tx < w and 0 <= ty < h and g[ty][tx] == 0:
                if tx == 0 or tx == w - 1 or ty == 0 or ty == h - 1:
                    print('INF')
                    return
                g[ty][tx] = 2
                q.put((tx, ty))
    #pprint(g)

    #ret = 0
    #for y in range(h):
    #    for x in range(w):
    #        if g[y][x] != 2:
    #            continue
    #        if x == 0 or x == w - 1 or y == 0 or y == h - 1:
    #            print('INF')
    #            return
    #        if x % 2 == 0 or y % 2 == 0:
    #            continue
    #        xx = sx[x // 2 + 1] - sx[x // 2]
    #        yy = sy[y // 2 + 1] - sy[y // 2]
    #        ret += xx * yy
    print(ret)
    return

def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    M = int(next(tokens))  # type: int
    A = [int()] * (N)  # type: "List[int]"
    B = [int()] * (N)  # type: "List[int]"
    C = [int()] * (N)  # type: "List[int]"
    for i in range(N):
        A[i] = int(next(tokens))
        B[i] = int(next(tokens))
        C[i] = int(next(tokens))
    D = [int()] * (M)  # type: "List[int]"
    E = [int()] * (M)  # type: "List[int]"
    F = [int()] * (M)  # type: "List[int]"
    for i in range(M):
        D[i] = int(next(tokens))
        E[i] = int(next(tokens))
        F[i] = int(next(tokens))
    solve(N, M, A, B, C, D, E, F)

if __name__ == '__main__':
    main()

Submission status: Time Limit Exceeded

Solution code:
#!/usr/bin/env python3

import sys
from pprint import pprint
sys.setrecursionlimit(300000)


def solve(N: int, M: int, A: "List[int]", B: "List[int]", C: "List[int]", D: "List[int]", E: "List[int]", F: "List[int]"):
    xs, ys = {}, {}
    xs[0] = 0
    ys[0] = 0
    for i in range(N):
        xs[A[i]] = 0
        xs[B[i]] = 0
        ys[C[i]] = 0
    for i in range(M):
        xs[D[i]] = 0
        ys[E[i]] = 0
        ys[F[i]] = 0

    sx, sy = [], []
    ox = sorted(xs.keys())
    for i, x in enumerate(ox):
        xs[x] = i
        sx.append(x)
    oy = sorted(ys.keys())
    for i, y in enumerate(oy):
        ys[y] = i
        sy.append(y)

    h, w = len(sy) * 2, len(sx) * 2
    g = [[0] * w for _ in range(h)]
    for i in range(N):
        y = ys[C[i]] * 2
        for x in range(xs[A[i]] * 2, xs[B[i]] * 2 + 1):
            g[y][x] = 1
    for i in range(M):
        x = xs[D[i]] * 2
        for y in range(ys[E[i]] * 2, ys[F[i]] * 2 + 1):
            g[y][x] = 1

    x, y = xs[0] * 2, ys[0] * 2
    g[y][x] = 2
    q = [(x, y)]
    dx = [0, -1, 0, 1]
    dy = [1, 0, -1, 0]
    #pprint(g)
    while True:
        nex = []
        for x, y in q:
            for k in range(len(dx)):
                tx, ty = x + dx[k], y + dy[k]
                if 0 <= tx < w and 0 <= ty < h and g[ty][tx] == 0:
                    g[ty][tx] = 2
                    nex.append((tx, ty))
        if len(nex) == 0:
            break
        q = nex
    #pprint(g)

    ret = 0
    for y in range(h):
        for x in range(w):
            if g[y][x] != 2:
                continue
            if x == 0 or x == w - 1 or y == 0 or y == h - 1:
                print('INF')
                return
            if x % 2 == 0 or y % 2 == 0:
                continue
            xx = sx[x // 2 + 1] - sx[x // 2]
            yy = sy[y // 2 + 1] - sy[y // 2]
            ret += xx * yy
    print(ret)
    return

def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    M = int(next(tokens))  # type: int
    A = [int()] * (N)  # type: "List[int]"
    B = [int()] * (N)  # type: "List[int]"
    C = [int()] * (N)  # type: "List[int]"
    for i in range(N):
        A[i] = int(next(tokens))
        B[i] = int(next(tokens))
        C[i] = int(next(tokens))
    D = [int()] * (M)  # type: "List[int]"
    E = [int()] * (M)  # type: "List[int]"
    F = [int()] * (M)  # type: "List[int]"
    for i in range(M):
        D[i] = int(next(tokens))
        E[i] = int(next(tokens))
        F[i] = int(next(tokens))
    solve(N, M, A, B, C, D, E, F)

if __name__ == '__main__':
    main()

Submission status: Time Limit Exceeded

Solution code:
import sys

def input(): return sys.stdin.readline().strip()
def list2d(a, b, c): return [[c] * b for i in range(a)]
def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]
def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]
def ceil(x, y=1): return int(-(-x // y))
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 9)
INF = 10 ** 18
MOD = 10 ** 9 + 7

def compress(S):
    """ 座標圧縮 """

    zipped, unzipped = {}, {}
    for i, a in enumerate(sorted(S)):
        zipped[a] = i
        unzipped[i] = a
    return zipped, unzipped

def bfs(grid, src):
    """ BFS(グリッド、重みなし) """
    from collections import deque

    H, W = len(grid), len(grid[0])
    directions = ((1, 0), (-1, 0), (0, 1), (0, -1))
    visited = list2d(H, W, 0)
    res = 0
    que = deque()
    for h, w in src:
        que.append((h, w))
        visited[h][w] = 1
        res += calc(h, w)
    while que:
        h, w = que.popleft()
        for dh, dw in directions:
            h2 = h + dh
            w2 = w + dw
            # 外壁まで行ったら即終了
            if grid[h2][w2] == -1:
                print('INF')
                exit()
            if grid[h2][w2] == 1:
                continue
            if visited[h2][w2]:
                continue
            visited[h2][w2] = 1
            res += calc(h2, w2)
            que.append((h2, w2))
    return res

def calc(i, j):
    # 対象は奇数マスだけ
    if i&1 and j&1:
        hln = unzph[i//2+1] - unzph[i//2]
        wln = unzpw[j//2+1] - unzpw[j//2]
        return hln * wln
    else:
        return 0

N, M = MAP()
vert = []
horz = []
S1 = set([0])
S2 = set([0])
for i in range(N):
    h1, h2, w = MAP()
    vert.append((h1, h2, w))
    S1.add(h1)
    S1.add(h2)
    S2.add(w)
for i in range(M):
    h, w1, w2 = MAP()
    horz.append((h, w1, w2))
    S1.add(h)
    S2.add(w1)
    S2.add(w2)

zph, unzph = compress(S1)
zpw, unzpw = compress(S2)
H, W = len(zph), len(zpw)

# グリッドの壁配置は全部2倍して考える
grid = list2d(H*2, W*2, -1)
for i in range(1, H*2-1):
    for j in range(1, W*2-1):
        grid[i][j] = 0
for i in range(N):
    h1, h2, w = vert[i]
    w = zpw[w] * 2
    for h in range(zph[h1]*2, zph[h2]*2+1):
        grid[h][w] = 1
for i in range(M):
    h, w1, w2 = horz[i]
    h = zph[h] * 2
    for w in range(zpw[w1]*2, zpw[w2]*2+1):
        grid[h][w] = 1

ans = bfs(grid, [(zph[0]*2, zpw[0]*2)])
print(ans)

Submission status: Time Limit Exceeded

Solution code:
import sys

def input(): return sys.stdin.readline().strip()
def list2d(a, b, c): return [[c] * b for i in range(a)]
def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]
def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]
def ceil(x, y=1): return int(-(-x // y))
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 9)
INF = 10 ** 18
MOD = 10 ** 9 + 7

def compress(S):
    """ 座標圧縮 """

    zipped, unzipped = {}, {}
    for i, a in enumerate(sorted(S)):
        zipped[a] = i
        unzipped[i] = a
    return zipped, unzipped

def bfs(grid, src):
    """ BFS(グリッド、重みなし) """
    from collections import deque

    H, W = len(grid), len(grid[0])
    directions = ((1, 0), (-1, 0), (0, 1), (0, -1))
    visited = list2d(H, W, 0)
    que = deque()
    for h, w in src:
        que.append((h, w))
        visited[h][w] = 1
    while que:
        h, w = que.popleft()
        for dh, dw in directions:
            h2 = h + dh
            w2 = w + dw
            # 外壁まで行ったら即終了
            if grid[h2][w2] == -1:
                print('INF')
                exit()
            if grid[h2][w2] == 1:
                continue
            if visited[h2][w2]:
                continue
            visited[h2][w2] = 1
            que.append((h2, w2))
    return visited

N, M = MAP()
vert = []
horz = []
S1 = set([0])
S2 = set([0])
for i in range(N):
    h1, h2, w = MAP()
    vert.append((h1, h2, w))
    S1.add(h1)
    S1.add(h2)
    S2.add(w)
for i in range(M):
    h, w1, w2 = MAP()
    horz.append((h, w1, w2))
    S1.add(h)
    S2.add(w1)
    S2.add(w2)

zph, unzph = compress(S1)
zpw, unzpw = compress(S2)
H, W = len(zph), len(zpw)

grid = list2d(H*2, W*2, -1)
for i in range(1, H*2-1):
    for j in range(1, W*2-1):
        grid[i][j] = 0
for i in range(N):
    h1, h2, w = vert[i]
    w = zpw[w] * 2
    for h in range(zph[h1]*2, zph[h2]*2+1):
        grid[h][w] = 1
for i in range(M):
    h, w1, w2 = horz[i]
    h = zph[h] * 2
    for w in range(zpw[w1]*2, zpw[w2]*2+1):
        grid[h][w] = 1

res = bfs(grid, [(zph[0]*2, zpw[0]*2)])
# for row in res:
#     print(row)

ans = 0
for i in range(1, H*2-1, 2):
    for j in range(1, W*2-1, 2):
        if res[i][j]:
            hln = unzph[i//2+1] - unzph[i//2]
            wln = unzpw[j//2+1] - unzpw[j//2]
            ans += hln * wln
print(ans)

Submission status: Time Limit Exceeded

Solution code:
def f_single_dot():
    # 参考: https://atcoder.jp/contests/abc168/submissions/13368489
    import sys
    from collections import deque
    input = sys.stdin.readline
    N, M = [int(i) for i in input().split()]

    x_set, y_set = set([0]), set([0])  # 重複を除いた xy 座標の一覧 (座標圧縮に必要)

    vertical_lines = []
    for _ in range(N):
        a, b, c = [int(i) for i in input().split()]
        vertical_lines.append((a, b, c))
        x_set |= {a, b}
        y_set |= {c}

    horizontal_lines = []
    for _ in range(M):
        d, e, f = [int(i) for i in input().split()]
        horizontal_lines.append((d, e, f))
        x_set |= {d}
        y_set |= {e, f}

    x_set = sorted(x_set)
    y_set = sorted(y_set)

    # 座標圧縮 (壁も配列に格納するので、2 倍している)
    x_encoded = {n: i * 2 for i, n in enumerate(x_set)}
    y_encoded = {n: i * 2 for i, n in enumerate(y_set)}
    # 座標圧縮されたグリッドで縦横に 1 マス分進むことは実際にはどれくらい進んだことなのか
    x_length = [x_set[i // 2 + 1] - x_set[i // 2] if i %
                2 else 0 for i in range(len(x_set) * 2 - 1)]
    y_length = [y_set[i // 2 + 1] - y_set[i // 2] if i %
                2 else 0 for i in range(len(y_set) * 2 - 1)]

    # 壁を埋めていく (累積和を用いていない)
    x_size, y_size = 2 * len(x_set) - 1, 2 * len(y_set) - 1
    grid = [[0] * y_size for _ in range(x_size)]
    for a, b, c in vertical_lines:
        a, b, c = x_encoded[a], x_encoded[b], y_encoded[c]
        for x in range(a, b + 1):
            grid[x][c] = 1
    for d, e, f in horizontal_lines:
        d, e, f = x_encoded[d], y_encoded[e], y_encoded[f]
        for y in range(e, f + 1):
            grid[d][y] = 1

    queue = deque()
    is_visited = [[0] * (y_size + 1) for _ in range(x_size + 1)]

    # 一度原点から斜めに動く (壁もグリッドに入れたため、ずれが生じたことによる)
    for dx, dy in ((-1, -1), (-1, 1), (1, 1), (1, -1)):
        nx, ny = x_encoded[0] + dx, y_encoded[0] + dy
        if 0 <= nx < x_size and 0 <= ny < y_size:
            queue.append((nx, ny))
            is_visited[nx][ny] = 1

    ans = 0
    while queue:
        x, y = queue.pop()
        if (x % 2) & (y % 2):
            ans += x_length[x] * y_length[y]
        # grid を 2 マスずつ動いているのは、壁をグリッドに入れたことによる
        for dx, dy in ((-1, 0), (1, 0), (0, -1), (0, 1)):
            nx, ny = x + dx, y + dy
            nnx, nny = nx + dx, ny + dy
            if grid[nx][ny] == 0:
                if not ((0 <= nnx < x_size) and (0 <= nny < y_size)):
                    return 'INF'
                if not is_visited[nnx][nny]:
                    queue.appendleft((nnx, nny))
                    is_visited[nnx][nny] = 1
    return ans

print(f_single_dot())

Submission status: Time Limit Exceeded

Solution code:
import sys
from collections import deque
def I():return int(input())
def LI():return [int(i) for i in input().split()]

def show(*inp,end='\n'):
    if show_flg:print(*inp,end=end)
mo=10**9+7
FourNb=[(-1,0),(1,0),(0,1),(0,-1)];EightNb=[(-1,0),(1,0),(0,1),(0,-1),(1,1),(-1,-1),(1,-1),(-1,1)];compas=dict(zip('WENS',FourNb));cursol=dict(zip('LRUD',FourNb))
#sys.setrecursionlimit(10**7)
input=lambda: sys.stdin.readline().rstrip()

show_flg=False
show_flg=True
ans=0
inf=1<<65
n,m=LI()
X=[0,inf,-inf]
Y=[0,inf,-inf]
V=[]
H=[]
for i in range(n):
    a,b,c=LI()
    V.append(((a,b),c))
    Y.append(c)
    X.append(a)
    X.append(b)

n+=2
V.append(((-inf,inf),inf))
V.append(((-inf,inf),-inf))

for i in range(m):
    a,b,c=LI()
    H.append((a,(b,c)))
    X.append(a)
    Y.append(b)
    Y.append(c)

m+=2
H.append((inf,(-inf,inf)))
H.append((-inf,(-inf,inf)))


X.sort()
xdc={}
c=1
for j in sorted(set(X)):
    xdc[c]=j
    c+=1
nx=c-1

Y.sort()
ydc={}
c=1
for j in sorted(set(Y)):
    ydc[c]=j
    c+=1
ny=c-1

xdcr=dict(zip(xdc.values(),xdc.keys()))
ydcr=dict(zip(ydc.values(),ydc.keys()))

mp=[[0]*(2*nx+2) for i in range(2*ny+2)]
mpx=[[0]*(2*nx+2) for i in range(2*ny+2)]
#mpy=[[0]*(2*nx+2) for i in range(2*ny+2)]

for (a,b),c in V:
    mpx[ydcr[c]*2][xdcr[a]*2]+=1
    mpx[ydcr[c]*2][xdcr[b]*2+1]+=-1
for i in range(0,2*ny+2,2):
    for j in range(2*nx+1):
        mpx[i][j+1]+=mpx[i][j]
        
for d,(e,f) in H:
    mp[ydcr[e]*2][xdcr[d]*2]+=1
    mp[ydcr[f]*2+1][xdcr[d]*2]+=-1
for j in range(0,2*nx+2,2):
    for i in range(2*ny+1):
        mp[i+1][j]+=mp[i][j]

for i in range(0,2*ny+2,2):
    for j in range(2*nx+2):
        mp[i][j]|=mpx[i][j]


v=[[0]*(2*nx+2) for i in range(2*ny+2)]
q=deque()
q.append((2*xdcr[0]+1,2*ydcr[0]+1))
v[2*ydcr[0]+1][2*xdcr[0]+1]=1
while q:
    cx,cy=q.popleft()
    px,py=cx>>1,cy>>1
    
    ans+=(xdc[px]-xdc[px+1])*(ydc[py]-ydc[py+1])
    #show((cx,cy),(xdc[px]-xdc[px-1])*(ydc[py]-ydc[py-1]),(xdc[px],xdc[px-1]),(ydc[py],ydc[py-1]))
    #show((cx,cy),px,py)
    for dx,dy in FourNb:
        nbx=cx+dx*2
        nby=cy+dy*2
        if (not 0<=nbx<2*nx+2) or (not 0<=nby<2*ny+2) or v[nby][nbx]==1:
            continue
        
        if mp[nby-dy][nbx-dx]==0:
            q.append((nbx,nby))
            v[nby][nbx]=1

if ans>=inf:
    ans='INF'
print(ans)

Submission status: Time Limit Exceeded

Solution code:
import sys
from collections import deque
def Golf():*a,=map(int,open(0))
def I():return int(input())
def S_():return input()
def IS():return input().split()
def LS():return [i for i in input().split()]
def LI():return [int(i) for i in input().split()]
def LI_():return [int(i)-1 for i in input().split()]
def NI(n):return [int(input()) for i in range(n)]
def NI_(n):return [int(input())-1 for i in range(n)]
def StoLI():return [ord(i)-97 for i in input()]
def ItoS(n):return chr(n+97)
def LtoS(ls):return ''.join([chr(i+97) for i in ls])
def GI(V,E,ls=None,Directed=False,index=1):
    org_inp=[];g=[[] for i in range(V)]
    FromStdin=True if ls==None else False
    for i in range(E):
        if FromStdin:
            inp=LI()
            org_inp.append(inp)
        else:
            inp=ls[i]
        if len(inp)==2:
            a,b=inp;c=1
        else:
            a,b,c=inp
        if index==1:a-=1;b-=1
        aa=(a,c);bb=(b,c);g[a].append(bb)
        if not Directed:g[b].append(aa)
    return g,org_inp
def GGI(h,w,search=None,replacement_of_found='.',mp_def={'#':1,'.':0},boundary=1):
#h,w,g,sg=GGI(h,w,search=['S','G'],replacement_of_found='.',mp_def={'#':1,'.':0},boundary=1) # sample usage
    mp=[boundary]*(w+2);found={}
    for i in range(h):
        s=input()
        for char in search:
            if char in s:
                found[char]=((i+1)*(w+2)+s.index(char)+1)
                mp_def[char]=mp_def[replacement_of_found]
        mp+=[boundary]+[mp_def[j] for j in s]+[boundary]
    mp+=[boundary]*(w+2)
    return h+2,w+2,mp,found
def TI(n):return GI(n,n-1)
def bit_combination(n,base=2):
    rt=[]
    for tb in range(base**n):s=[tb//(base**bt)%base for bt in range(n)];rt+=[s]
    return rt
def gcd(x,y):
    if y==0:return x
    if x%y==0:return y
    while x%y!=0:x,y=y,x%y
    return y
def show(*inp,end='\n'):
    if show_flg:print(*inp,end=end)
mo=10**9+7
FourNb=[(-1,0),(1,0),(0,1),(0,-1)];EightNb=[(-1,0),(1,0),(0,1),(0,-1),(1,1),(-1,-1),(1,-1),(-1,1)];compas=dict(zip('WENS',FourNb));cursol=dict(zip('LRUD',FourNb))
#sys.setrecursionlimit(10**7)
input=lambda: sys.stdin.readline().rstrip()

show_flg=False
show_flg=True
ans=0
inf=1<<70
n,m=LI()
X=[0,inf,-inf]
Y=[0,inf,-inf]
V=[]
H=[]
for i in range(n):
    a,b,c=LI()
    V.append(((a,b),c))
    Y.append(c)
    X.append(a)
    X.append(b)

n+=2
V.append(((-inf,inf),inf))
V.append(((-inf,inf),-inf))

for i in range(m):
    a,b,c=LI()
    H.append((a,(b,c)))
    X.append(a)
    Y.append(b)
    Y.append(c)

m+=2
H.append((inf,(-inf,inf)))
H.append((-inf,(-inf,inf)))


X.sort()
xdc={}
c=1
for j in sorted(set(X)):
    xdc[c]=j
    c+=1
nx=c-1

Y.sort()
ydc={}
c=1
for j in sorted(set(Y)):
    ydc[c]=j
    c+=1
ny=c-1

xdcr=dict(zip(xdc.values(),xdc.keys()))
ydcr=dict(zip(ydc.values(),ydc.keys()))

mp=[[0]*(2*nx+2) for i in range(2*ny+2)]
mpx=[[0]*(2*nx+2) for i in range(2*ny+2)]
#mpy=[[0]*(2*nx+2) for i in range(2*ny+2)]

for (a,b),c in V:
    mpx[ydcr[c]*2][xdcr[a]*2]+=1
    mpx[ydcr[c]*2][xdcr[b]*2+1]+=-1
for i in range(0,2*ny+2,2):
    for j in range(2*nx+1):
        mpx[i][j+1]+=mpx[i][j]
        
for d,(e,f) in H:
    mp[ydcr[e]*2][xdcr[d]*2]+=1
    mp[ydcr[f]*2+1][xdcr[d]*2]+=-1
for j in range(0,2*nx+2,2):
    for i in range(2*ny+1):
        mp[i+1][j]+=mp[i][j]

for i in range(0,2*ny+2,2):
    for j in range(2*nx+2):
        mp[i][j]|=mpx[i][j]


v=[[0]*(2*nx+2) for i in range(2*ny+2)]
q=deque()
q.append((2*xdcr[0]+1,2*ydcr[0]+1))
v[2*ydcr[0]+1][2*xdcr[0]+1]=1
while q:
    cx,cy=q.popleft()
    px,py=cx>>1,cy>>1
    
    ans+=(xdc[px]-xdc[px+1])*(ydc[py]-ydc[py+1])
    #show((cx,cy),(xdc[px]-xdc[px-1])*(ydc[py]-ydc[py-1]),(xdc[px],xdc[px-1]),(ydc[py],ydc[py-1]))
    #show((cx,cy),px,py)
    for dx,dy in FourNb:
        nbx=cx+dx*2
        nby=cy+dy*2
        if (not 0<=nbx<2*nx+2) or (not 0<=nby<2*ny+2) or v[nby][nbx]==1:
            continue
        
        if mp[nby-dy][nbx-dx]==0:
            q.append((nbx,nby))
            v[nby][nbx]=1

if ans>=inf:
    ans='INF'
print(ans)