結果

問題 No.579 3 x N グリッド上のサイクルのサイズ(hard)
ユーザー maspy
提出日時 2020-05-06 18:23:41
言語 Python3
(3.13.1 + numpy 2.2.1 + scipy 1.14.1)
結果
AC  
実行時間 684 ms / 2,000 ms
コード長 2,982 bytes
コンパイル時間 94 ms
コンパイル使用メモリ 13,056 KB
実行使用メモリ 44,948 KB
最終ジャッジ日時 2024-07-03 09:05:39
合計ジャッジ時間 44,679 ms
ジャッジサーバーID
(参考情報)
judge1 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 80
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

import sys
import numpy as np
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
#
MOD = 10**9 + 7
def compute_next_status(status, vertical):
status = list(status)
deg = [0] * 4
for i, x in enumerate(status):
if x != 0:
deg[i] = 1
loop = False
for i in range(3):
if vertical & (1 << i):
deg[i] += 1
deg[i+1] += 1
if status[i] == status[i+1] != 0:
if loop:
return None
loop = True
status[i] = status[i+1] = 0
continue
if status[i] == status[i+1] == 0:
status[i] = status[i+1] = max(status) + 1
elif status[i] != 0 and status[i+1] == 0:
status[i+1] = status[i]
elif status[i+1] != 0 and status[i] == 0:
status[i] = status[i+1]
else:
n, m = status[i:i+2]
n, m = max(n, m), min(n, m)
for v in range(4):
if status[v] == m:
status[v] = n
if loop:
if any(x in [1,3] for x in deg):
return None
return (0,0,0,0)
if any(x >= 3 for x in deg):
return None
for v in range(4):
if deg[v] != 1:
status[v] = 0
for n, k in enumerate(set(status + [0])):
if k == 0:
continue
for v in range(4):
if status[v] == k:
status[v] = n
return tuple(status)
visited = set([(0,0,0,0)])
q = [(0,0,0,0)]
edges = [] #
popcount = [0,1,1,2,1,2,2,3]
while q:
v = q.pop()
for i in range(8):
w = compute_next_status(v, i)
if w is None:
continue
edges.append((v,w, popcount[i] + sum(x != 0 for x in w)))
if w in visited:
continue
visited.add(w)
q.append(w)
L = len(visited) + 1
A = np.zeros((2*L,2*L), dtype=object)
v_to_i = {v:i for i,v in enumerate(visited)}
i0 = v_to_i[(0,0,0,0)]
i_end = L - 1
for v,w,k in edges:
iv, iw = v_to_i[v], v_to_i[w]
if iv != i0 and iw == i0:
iw = i_end
A[2*iw, 2*iv] = 1 # ->
A[2*iw+1, 2*iv] = k # ->
A[2*iw+1,2*iv+1] = 1 # ->
A[2*i_end, 2*i_end] += 1
A[2*i_end+1, 2*i_end+1] += 1
def mult_mod(A, B, MOD=MOD):
mask = (1<<15) - 1
A1, A2 = A>>15, A & mask
B1, B2 = B>>15, B&mask
X = np.dot(A1, B1) % MOD
Z = np.dot(A2, B2) % MOD
Y = (np.dot(A1+A2,B1+B2)-X-Z)%MOD
return ((X<<30)+(Y<<15)+Z)%MOD
def matrix_power(A, n, MOD=MOD):
if n == 1:
return A
B = matrix_power(A, n//2)
B = mult_mod(B, B)
if n & 1:
B = mult_mod(A, B)
return B
N = int(read())
print(matrix_power(A, N + 1)[2*i_end+1, 2*i0])
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0