結果
| 問題 |
No.541 3 x N グリッド上のサイクルの個数
|
| コンテスト | |
| ユーザー |
maspy
|
| 提出日時 | 2020-05-06 18:08:01 |
| 言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
| 結果 |
AC
|
| 実行時間 | 538 ms / 2,000 ms |
| コード長 | 2,647 bytes |
| コンパイル時間 | 87 ms |
| コンパイル使用メモリ | 12,928 KB |
| 実行使用メモリ | 44,912 KB |
| 最終ジャッジ日時 | 2024-07-03 09:03:41 |
| 合計ジャッジ時間 | 33,868 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 62 |
ソースコード
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 = []
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))
if w in visited:
continue
visited.add(w)
q.append(w)
visited
L = len(visited) + 1
A = np.zeros((L,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 in edges:
iv, iw = v_to_i[v], v_to_i[w]
if iv != i0 and iw == i0:
iw = i_end
A[iw, iv] = 1
A[i_end, i_end] += 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
MOD = 10**9 + 7
N = int(read())
print(matrix_power(A, N + 1)[i_end, i0])
maspy