結果
問題 | No.1561 connect x connect |
ユーザー | maspy |
提出日時 | 2021-04-11 13:31:43 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
(最新)
AC
(最初)
|
実行時間 | - |
コード長 | 4,148 bytes |
コンパイル時間 | 221 ms |
コンパイル使用メモリ | 82,264 KB |
実行使用メモリ | 173,192 KB |
最終ジャッジ日時 | 2024-06-25 07:57:37 |
合計ジャッジ時間 | 9,361 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 40 ms
60,736 KB |
testcase_01 | AC | 118 ms
76,988 KB |
testcase_02 | AC | 275 ms
79,388 KB |
testcase_03 | AC | 40 ms
53,604 KB |
testcase_04 | AC | 44 ms
60,396 KB |
testcase_05 | AC | 52 ms
63,928 KB |
testcase_06 | AC | 39 ms
53,076 KB |
testcase_07 | AC | 40 ms
54,916 KB |
testcase_08 | AC | 46 ms
61,224 KB |
testcase_09 | AC | 45 ms
61,404 KB |
testcase_10 | AC | 51 ms
64,004 KB |
testcase_11 | AC | 118 ms
77,152 KB |
testcase_12 | AC | 179 ms
78,732 KB |
testcase_13 | AC | 272 ms
79,080 KB |
testcase_14 | AC | 653 ms
95,060 KB |
testcase_15 | AC | 664 ms
95,196 KB |
testcase_16 | AC | 297 ms
79,004 KB |
testcase_17 | AC | 120 ms
76,992 KB |
testcase_18 | AC | 54 ms
63,932 KB |
testcase_19 | AC | 770 ms
95,188 KB |
testcase_20 | AC | 185 ms
78,608 KB |
testcase_21 | AC | 46 ms
61,764 KB |
testcase_22 | AC | 187 ms
78,748 KB |
testcase_23 | AC | 47 ms
61,480 KB |
testcase_24 | AC | 769 ms
95,064 KB |
testcase_25 | AC | 49 ms
62,864 KB |
testcase_26 | TLE | - |
testcase_27 | -- | - |
testcase_28 | -- | - |
testcase_29 | -- | - |
testcase_30 | -- | - |
testcase_31 | -- | - |
testcase_32 | -- | - |
testcase_33 | -- | - |
testcase_34 | -- | - |
testcase_35 | -- | - |
testcase_36 | -- | - |
testcase_37 | -- | - |
ソースコード
MOD = 1_000_000_007 def to(H, A): """ empty col """ if A == 'begin': yield 'begin' elif A == 'end': yield 'end' elif len(set(x for x in A if x >= 0)) == 1: yield 'end' if A == 'end': return _A = A for s in range(1, 1 << H): if _A == 'begin' or _A == 'end': A = [-1] * H else: A = list(_A) for i in range(H): if A[i] >= 0: A[i] += H for i in range(H): if s & 1 << i: A.append(i) else: A.append(-1) """ 横にマージ """ for i in range(H): j = i + H if A[i] >= 0 and A[j] >= 0 and A[i] != A[j]: before = max(A[i], A[j]) after = min(A[i], A[j]) for k in range(H + H): if A[k] == before: A[k] = after """ 縦にマージ """ for i in range(H, H + H - 1): j = i + 1 if A[i] >= 0 and A[j] >= 0 and A[i] != A[j]: before = max(A[i], A[j]) after = min(A[i], A[j]) for k in range(H + H): if A[k] == before: A[k] = after if any(x >= H for x in A[:H]): # 孤立した連結成分が残ってしまった場合 continue yield tuple(A[H:]) def flip(A): H = len(A) A = list(A[::-1]) for i in range(H): if A[i] != -1: A[i] = H - 1 - A[i] for i in range(H): if A[i] > i: before = A[i] after = i for j in range(H): if A[j] == before: A[j] = after return tuple(A) def generate_graph_compress(H): """ mirror reflection を同一視して、状態を圧縮する """ V = ['begin', 'end'] ID = {'begin': 0, 'end': 1} G = [] for i, v in enumerate(V): for w in to(H, v): if w == 'begin' or w == 'end': pass else: w = min(w, flip(w)) if w not in ID: ID[w] = len(V) V.append(w) j = ID[w] G.append((i, j)) return len(V), G """ N = 436 に対して (N,N) 行列の 10^18 乗あたりを求めることになる。厳しい。 線形漸化式を、前計算することにする。 """ def conv(A, B): C = [0] * (len(A) + len(B) - 1) for i in range(len(A)): for j in range(len(B)): C[i + j] += A[i] * B[j] C[i + j] %= MOD return C def coef_of_generating_function(P, Q, N): assert Q[0] == 1 and len(Q) == len(P) + 1 while N: Q1 = Q.copy() for i in range(len(Q)): if i & 1: Q1[i] = -Q1[i] P = conv(P, Q1)[N & 1::2] Q = conv(Q, Q1)[::2] N >>= 1 return P[0] def find_generating_function(A): N = len(A) B = [1] C = [1] l, m, p = 0, 1, 1 for i in range(N): d = A[i] for j in range(1, l + 1): d += C[j] * A[i - j] d %= MOD if d == 0: m += 1 continue T = C.copy() q = pow(p, MOD - 2, MOD) * d % MOD if len(C) < len(B) + m: C += [0] * (len(B) + m - len(C)) for j in range(len(B)): C[j + m] -= q * B[j] C[j + m] %= MOD if l + l <= i: B = T l, m, p = i + 1 - l, 1, d else: m += 1 Q = C P = conv(A, Q)[:len(Q) - 1] return P, Q def solve_small(H): N, G = generate_graph_compress(H) FRM, TO = map(list, zip(*G)) MAX = N + N + 10 ans = [0] * MAX dp = [0] * N dp[0] = 1 for i in range(MAX): newdp = [0] * N for a, b in G: newdp[b] += dp[a] dp = [x % MOD for x in newdp] ans[i] = dp[1] return ans H, W = map(int, input().split()) A = solve_small(H) P, Q = find_generating_function(A) print(coef_of_generating_function(P, Q, W))