結果
| 問題 |
No.274 The Wall
|
| コンテスト | |
| ユーザー |
lam6er
|
| 提出日時 | 2025-03-31 17:36:53 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 1,579 ms / 2,000 ms |
| コード長 | 3,543 bytes |
| コンパイル時間 | 221 ms |
| コンパイル使用メモリ | 82,780 KB |
| 実行使用メモリ | 322,736 KB |
| 最終ジャッジ日時 | 2025-03-31 17:37:35 |
| 合計ジャッジ時間 | 9,253 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 23 |
ソースコード
import sys
from sys import stdin
sys.setrecursionlimit(1 << 25)
def main():
N, M = map(int, stdin.readline().split())
blocks = []
for _ in range(N):
L, R = map(int, stdin.readline().split())
flipped_L = (M - 1) - R
flipped_R = (M - 1) - L
original = (L, R)
flipped = (flipped_L, flipped_R)
blocks.append((original, flipped))
# Build implication graph
adj = [[] for _ in range(2 * N)] # 2N literals (var and neg)
for i in range(N):
for j in range(i + 1, N):
block_i = blocks[i]
block_j = blocks[j]
for a in [0, 1]:
i_start, i_end = block_i[a]
for b in [0, 1]:
j_start, j_end = block_j[b]
# Check overlap
overlap = not (i_end < j_start or j_end < i_start)
if overlap:
# Compute literals for the clause
if a == 1:
l_i = 2 * i + 1 # ~var_i
else:
l_i = 2 * i # var_i
if b == 1:
l_j = 2 * j + 1 # ~var_j
else:
l_j = 2 * j # var_j
# Add implications: ~l_i -> l_j and ~l_j -> l_i
# Edge 1: ~l_i -> l_j
complement_l_i = l_i ^ 1
adj[complement_l_i].append(l_j)
# Edge 2: ~l_j -> l_i
complement_l_j = l_j ^ 1
adj[complement_l_j].append(l_i)
# Tarjan's algorithm to find SCC iteratively
index = 0
indices = [-1] * (2 * N)
low = [0] * (2 * N)
in_stack = [False] * (2 * N)
scc_id = [0] * (2 * N)
scc_count = 0
stack = []
for u in range(2 * N):
if indices[u] == -1:
stack_ = [(u, iter(adj[u]))]
indices[u] = index
low[u] = index
index += 1
path = [u]
in_stack[u] = True
dfs_stack = []
while stack_:
node, neighbors = stack_[-1]
try:
v = next(neighbors)
if indices[v] == -1:
indices[v] = index
low[v] = index
index += 1
stack_.append((v, iter(adj[v])))
path.append(v)
in_stack[v] = True
else:
if in_stack[v]:
low[node] = min(low[node], indices[v])
except StopIteration:
stack_.pop()
if stack_:
parent = stack_[-1][0]
low[parent] = min(low[parent], low[node])
if low[node] == indices[node]:
while True:
w = path.pop()
in_stack[w] = False
scc_id[w] = scc_count
if w == node:
break
scc_count += 1
# Check for any variable and its negation in the same SCC
possible = True
for i in range(N):
if scc_id[2 * i] == scc_id[2 * i + 1]:
possible = False
break
print("YES" if possible else "NO")
if __name__ == "__main__":
main()
lam6er