結果
| 問題 |
No.261 ぐるぐるぐるぐる!あみだくじ!
|
| コンテスト | |
| ユーザー |
lam6er
|
| 提出日時 | 2025-03-20 20:51:46 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 58 ms / 5,000 ms |
| コード長 | 4,033 bytes |
| コンパイル時間 | 161 ms |
| コンパイル使用メモリ | 82,532 KB |
| 実行使用メモリ | 69,064 KB |
| 最終ジャッジ日時 | 2025-03-20 20:51:59 |
| 合計ジャッジ時間 | 3,355 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 37 |
ソースコード
import sys
from math import gcd
def extended_gcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = extended_gcd(b % a, a)
return (g, x - (b // a) * y, y)
def crt(congruences):
x, mod = 0, 1
for a, m in congruences:
g, p, q = extended_gcd(mod, m)
if (a - x) % g != 0:
return (0, 0)
lcm = mod // g * m
tmp = (( (a - x) // g * p ) % (m // g)) * mod
x += tmp
mod = lcm
x %= mod
return (x, mod)
def compute_p(N, swaps):
perm = list(range(N))
for j in range(N):
pos = j
for (x, y) in swaps:
if pos == x:
pos = y
elif pos == y:
pos = x
perm[j] = pos
return perm
def find_cycles(perm):
visited = [False] * len(perm)
cycles = []
for i in range(len(perm)):
if not visited[i]:
cycle = []
current = i
while not visited[current]:
visited[current] = True
cycle.append(current)
current = perm[current]
cycles.append(cycle)
return cycles
def array_to_perm(A):
perm = [0] * len(A)
for i in range(len(A)):
val = A[i]
perm[val - 1] = i # val-1 is 0-based, perm[val-1] is the index i where val is located
return perm
def compose(p1, p2):
# compute p1 after p2: p1[p2[x]]
return [ p1[x] for x in p2 ]
def permutation_power(perm, t):
N = len(perm)
result = list(range(N))
current = perm.copy()
while t > 0:
if t % 2 == 1:
result = compose(result, current)
current = compose(current, current)
t = t // 2
return result
def main():
input = sys.stdin.read().split()
ptr = 0
N = int(input[ptr])
ptr +=1
K = int(input[ptr])
ptr +=1
swaps = []
for _ in range(K):
X = int(input[ptr]) -1
Y = int(input[ptr+1]) -1
ptr +=2
swaps.append( (X, Y) )
perm_p = compute_p(N, swaps)
cycles_p = find_cycles(perm_p)
Q = int(input[ptr])
ptr +=1
for _ in range(Q):
A = list(map(int, input[ptr:ptr+N]))
ptr +=N
perm_q = array_to_perm(A)
valid = True
congruences = []
for cycle in cycles_p:
L = len(cycle)
cycle_set = set(cycle)
for x in cycle:
current = x
visited = set()
while True:
if current not in cycle_set:
valid = False
break
if current in visited:
valid = False
break
visited.add(current)
current = perm_q[current]
if current == x:
break
if not valid:
break
if not valid:
break
index_in_cycle = {x:i for i, x in enumerate(cycle)}
s = None
x0 = cycle[0]
q_x0 = perm_q[x0]
pos_q_x0 = index_in_cycle.get(q_x0, -1)
if pos_q_x0 == -1:
valid = False
break
s_candidate = (pos_q_x0 - 0) % L
for x in cycle:
expected_pos = (index_in_cycle[x] + s_candidate) % L
expected_x = cycle[expected_pos]
if perm_q[x] != expected_x:
valid = False
break
if not valid:
break
congruences.append( (s_candidate, L) )
if not valid:
print(-1)
continue
x, mod = crt(congruences)
if mod == 0:
print(-1)
continue
t = x if x !=0 else mod
if t <1:
t += mod
p_t = permutation_power(perm_p, t)
if p_t == perm_q:
print(t)
else:
print(-1)
if __name__ == "__main__":
main()
lam6er