結果
問題 | No.950 行列累乗 |
ユーザー | maspy |
提出日時 | 2019-12-13 23:42:36 |
言語 | Python3 (3.12.2 + numpy 1.26.4 + scipy 1.12.0) |
結果 |
RE
|
実行時間 | - |
コード長 | 4,150 bytes |
コンパイル時間 | 83 ms |
コンパイル使用メモリ | 13,184 KB |
実行使用メモリ | 70,652 KB |
最終ジャッジ日時 | 2024-06-27 21:51:35 |
合計ジャッジ時間 | 39,073 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | RE | - |
testcase_01 | RE | - |
testcase_02 | AC | 513 ms
44,236 KB |
testcase_03 | RE | - |
testcase_04 | RE | - |
testcase_05 | AC | 645 ms
62,604 KB |
testcase_06 | AC | 513 ms
44,500 KB |
testcase_07 | AC | 513 ms
43,976 KB |
testcase_08 | WA | - |
testcase_09 | AC | 519 ms
44,368 KB |
testcase_10 | AC | 520 ms
44,616 KB |
testcase_11 | AC | 527 ms
44,492 KB |
testcase_12 | AC | 525 ms
44,364 KB |
testcase_13 | WA | - |
testcase_14 | WA | - |
testcase_15 | AC | 522 ms
44,240 KB |
testcase_16 | WA | - |
testcase_17 | RE | - |
testcase_18 | RE | - |
testcase_19 | RE | - |
testcase_20 | RE | - |
testcase_21 | AC | 682 ms
69,416 KB |
testcase_22 | WA | - |
testcase_23 | AC | 650 ms
63,632 KB |
testcase_24 | AC | 639 ms
61,836 KB |
testcase_25 | AC | 627 ms
59,176 KB |
testcase_26 | AC | 669 ms
65,180 KB |
testcase_27 | AC | 649 ms
62,496 KB |
testcase_28 | WA | - |
testcase_29 | WA | - |
testcase_30 | AC | 652 ms
62,476 KB |
testcase_31 | WA | - |
testcase_32 | WA | - |
testcase_33 | AC | 660 ms
62,732 KB |
testcase_34 | WA | - |
testcase_35 | WA | - |
testcase_36 | RE | - |
testcase_37 | RE | - |
testcase_38 | RE | - |
testcase_39 | RE | - |
testcase_40 | AC | 706 ms
70,028 KB |
testcase_41 | AC | 697 ms
70,644 KB |
testcase_42 | AC | 703 ms
70,312 KB |
testcase_43 | WA | - |
testcase_44 | WA | - |
testcase_45 | AC | 713 ms
70,136 KB |
testcase_46 | WA | - |
testcase_47 | WA | - |
testcase_48 | WA | - |
testcase_49 | WA | - |
testcase_50 | WA | - |
testcase_51 | WA | - |
testcase_52 | RE | - |
testcase_53 | RE | - |
testcase_54 | RE | - |
testcase_55 | RE | - |
testcase_56 | RE | - |
testcase_57 | AC | 697 ms
70,652 KB |
testcase_58 | WA | - |
testcase_59 | RE | - |
testcase_60 | RE | - |
ソースコード
import sys read = sys.stdin.buffer.read readline = sys.stdin.buffer.readline readlines = sys.stdin.buffer.readlines import numpy as np import itertools MOD = int(readline()) data = list(map(int,read().split())) A = np.int64(data[:4]).reshape(2,2) B = np.int64(data[4:]).reshape(2,2) def make_power_mat(A, L, MOD=MOD): N = A.shape[0] assert A.shape == (N,N) B = L.bit_length() x = np.empty((1<<B,N,N), np.int64) x[0] = np.eye(N,dtype=np.int64) X = A.copy() for n in range(B): for i,j in itertools.product(range(N),repeat=2): x[1<<n:1<<(n+1),i,j] = (x[:1<<n,i,:] * X[:,j] % MOD).sum(axis=1) % MOD Y = X.copy() for i,j in itertools.product(range(N),repeat=2): X[i,j] = (Y[i,:] * Y[:,j] % MOD).sum() % MOD return x[:L] def make_power(a, L, MOD=MOD): B = L.bit_length() x = np.empty((1<<B), np.int64) x[0] = 1 for n in range(B): x[1<<n:1<<(n+1)] = x[:1<<n] * a % MOD a *= a; a %= MOD return x[:L] def BSGS(a,b,MOD): assert a != 0 M = int(MOD ** .5 + 100) c = pow(int(a),M,MOD) d = pow(int(a),MOD-2,MOD) B = make_power(d,M,MOD) G = make_power(c,M,MOD) I = np.in1d(G, b * B % MOD) if not I.any(): return -1 q = np.where(I)[0][0] r = np.where(b * B % MOD == G[q])[0][0] return q * M + r def solve_naive(A,B,MOD): X = np.int64([[1,0],[0,1]]) for n in range(1,10**4): X = np.dot(X,A) % MOD if (X == B).all(): return n return -1 def matrix_power(A,n,MOD): if n == 0: return np.eye(2,dtype=np.int64) B = matrix_power(A,n//2,MOD) B = np.dot(B,B) % MOD return np.dot(A,B) % MOD if n & 1 else B def matrix_inverse(A,MOD): # powerでもよいが det = (A[0,0]*A[1,1] - A[1,0]*A[0,1]) % MOD B = np.array([ [A[1,1],-A[0,1]], [-A[1,0],A[0,0]], ]) x = pow(int(det),MOD-2,MOD) B *= x; B %= MOD assert np.all(np.dot(A,B) % MOD == np.eye(2,dtype=np.int64)) return B def solve(A,B,MOD): if MOD == 2: return solve_naive(A,B,MOD) detA = (A[0,0]*A[1,1] - A[1,0]*A[0,1]) % MOD detB = (B[0,0]*B[1,1] - B[1,0]*B[0,1]) % MOD trA = (A[0,0] + A[1,1]) % MOD if detA == 0 and trA == 0: # べき零 if (A == B).all(): return 1 if (B == 0).all(): return 2 return -1 if detA == 0: # A^n = t^{n-1}A I,J = np.where(A != 0); i = I[0]; j = J[0] a = A[i,j]; b = B[i,j] k = b * pow(int(a),MOD-2,MOD) % MOD assert a * k % MOD == b n = BGSG(trA,k,MOD) return -1 if n == -1 else n + 1 # det A == 1 に帰着したい n = BSGS(detA,detB,MOD) if n == -1: return -1 e = BSGS(detA,1,MOD) Ainv = matrix_inverse(A,MOD) B = np.dot(B,matrix_power(Ainv,n,MOD)) % MOD A = matrix_power(A,e,MOD) k = solve_SL2(A,B,MOD) if k == -1: return -1 return e * k + n def to_hash(A): A = A.astype(object) return (A[:,0,0] << 96) + (A[:,1,0] << 64) + (A[:,0,1] << 32) + (A[:,1,1]) def solve_SL2(A,B,MOD): """ A の固有値を考えると、Aの位数は十分小さいことが分かる F_pで2固有値 → p-1周期 F_{p^2}で2固有値 → ノルム1にしたのでp+1周期 固有値が重複 → 2乗すると固有値が1 → 2p周期 2p程度で、BGSGをすればよい """ U = 2 * MOD M = int(U ** .5 + 100) c = matrix_power(A,M,MOD) d = matrix_inverse(A,MOD) Baby = make_power_mat(d,M,MOD) Giant = make_power_mat(c,M,MOD) BB = np.zeros((M,2,2),np.int64) for i,j in itertools.product(range(2),repeat=2): BB[:,i,j] = (Baby[:,i,:] * B[:,j][None,:] % MOD).sum(axis=1) % MOD Gh = to_hash(Giant).tolist() BBh = to_hash(BB).tolist() se = set(BBh) q = -1 for i,g in enumerate(Gh): if g in se: q = i break if q == -1: return -1 g = Gh[q] r = -1 for i,b in enumerate(BBh): if b == g: r = i break return q * M + r print(solve_SL2(A,B,MOD))