結果
| 問題 |
No.274 The Wall
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-09-26 13:49:45 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
MLE
|
| 実行時間 | - |
| コード長 | 4,363 bytes |
| コンパイル時間 | 131 ms |
| コンパイル使用メモリ | 82,444 KB |
| 実行使用メモリ | 849,304 KB |
| 最終ジャッジ日時 | 2024-06-29 01:04:59 |
| 合計ジャッジ時間 | 3,866 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 4 |
| other | AC * 3 MLE * 1 -- * 18 |
ソースコード
class CSR:
def __init__(self, n: int, edges: list):
self.start = [0] * (n + 1)
self.elist = [0] * len(edges)
for e in edges:
self.start[e[0] + 1] += 1
for i in range(1, n + 1):
self.start[i] += self.start[i - 1]
counter = self.start[::] # copy
for e in edges:
self.elist[counter[e[0]]] = e[1]
counter[e[0]] += 1
class SccGraph:
def __init__(self, n: int = 0):
self.__n = n
self.__edges = []
def __len__(self):
return self.__n
def add_edge(self, s: int, t: int):
assert 0 <= s < self.__n and 0 <= t < self.__n
self.__edges.append([s, t])
def scc_ids(self):
g = CSR(self.__n, self.__edges)
now_ord = group_num = 0
visited = []
low = [0] * self.__n
order = [-1] * self.__n
ids = [0] * self.__n
parent = [-1] * self.__n
for root in range(self.__n):
if order[root] == -1:
stack = [root, root]
while stack:
v = stack.pop()
if order[v] == -1:
visited.append(v)
low[v] = order[v] = now_ord
now_ord += 1
for i in range(g.start[v], g.start[v + 1]):
t = g.elist[i]
if order[t] == -1:
stack += [t, t]
parent[t] = v
else:
low[v] = min(low[v], order[t])
else:
if low[v] == order[v]:
while True:
u = visited.pop()
order[u] = self.__n
ids[u] = group_num
if u == v:
break
group_num += 1
if parent[v] != -1:
low[parent[v]] = min(low[parent[v]], low[v])
for i, x in enumerate(ids):
ids[i] = group_num - 1 - x
return group_num, ids
def scc(self):
"""
強連結成分のリストを返す。この時、リストはトポロジカルソートされている
[[強連結成分のリスト], [強連結成分のリスト], ...]
"""
group_num, ids = self.scc_ids()
counts = [0] * group_num
for x in ids:
counts[x] += 1
groups = [[] for _ in range(group_num)]
for i, x in enumerate(ids):
groups[x].append(i)
return groups
class TwoSAT():
def __init__(self, n):
self.n = n
self.res = [0]*self.n
self.scc = SccGraph(2*n)
def add_clause(self, i, f, j, g):
# assert 0 <= i < self.n
# assert 0 <= j < self.n
self.scc.add_edge(2*i + (not f), 2*j + g)
self.scc.add_edge(2*j + (not g), 2*i + f)
def satisfiable(self):
"""
条件を足す割当が存在するかどうかを判定する。割当が存在するならばtrue、そうでないならfalseを返す。
"""
group_num, ids = self.scc.scc_ids()
for i in range(self.n):
if ids[2*i] == ids[2*i + 1]: return False
self.res[i] = (ids[2*i] < ids[2*i+1])
return True
def result(self):
"""
最後に呼んだ satisfiable の、クローズを満たす割当を返す。
"""
return self.res
def f(l, r, l1, r1):
return l <= l1 <= r or l <= r1 <= r or l1 <= l <= r1 or l1 <= r <= r1
#############################################################################
import sys
input = sys.stdin.readline
N, M = map(int, input().split())
data = []
for _ in range(N):
L, R = map(int, input().split())
data.append((L, R))
ts = TwoSAT(N)
for i in range(N):
for j in range(i+1, N):
l, r = data[i]
l1, r1 = data[j]
if f(l, r, l1, r1): ts.add_clause(i,1,j,1)
if f(M-r-1, M-l-1, l1, r1): ts.add_clause(i,0,j,1)
if f(l, r, M-r1-1, M-l1-1): ts.add_clause(i,1,j,0)
if f(M-r-1, M-l-1, M-r1-1, M-l1-1): ts.add_clause(i,0,j,0)
print("YES" if ts.satisfiable() else "NO")