結果
| 問題 | No.8038 フィボナッチ数列の周期 |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-10-23 14:02:45 |
| 言語 | PyPy3 (8.0.0 + ACL) |
| 結果 |
AC
不安定
|
| 実行時間 | 745 ms / 3,000 ms |
| + 656µs | |
| コード長 | 3,206 bytes |
| 記録 | |
| コンパイル時間 | 90 ms |
| コンパイル使用メモリ | 64,716 KB |
| 実行使用メモリ | 220,800 KB |
| 最終ジャッジ日時 | 2026-10-23 14:03:08 |
| 合計ジャッジ時間 | 19,801 ms |
|
ジャッジサーバーID (参考情報) |
judge3_0 / judge1_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 25 |
ソースコード
def sieves(nn: int):
# is_prime = [True] * nn
least_p = [-1] * nn
least_p[0] = 0
least_p[1] = 1
for p in range(2, nn):
if least_p[p] != -1:
continue
least_p[p] = p
for q in range(p * 2, nn, p):
if least_p[q] == -1:
least_p[q] = p
# primes = [p for p in range(2, nn) if is_prime[p]]
# return is_prime, least_p # , primes, mobius
return least_p
def prime_factorize(n: int):
ans = {}
while n > 1:
p = least_p[n]
e = 0
while n % p == 0:
n //= p
e += 1
ans[p] = e
return ans
def get_divisors(n: int):
"""正の約数列挙
Args:
n (int): 約数を求める数 (>= 1)
Returns:
list[int]: `n`の正の約数
Notes:
- `n`の約数の個数をσ(n)として
- 計算量 Θ( σ(n) * log(σ(n)) )
- n <= 10^7 で σ(n) <= σ(8648640) = 448
- n <= 10^9 で σ(n) <= σ(735134400) = 1344
- n <= 10^18 で σ(n) <= σ(897612484786617600) = 103680
"""
pe = prime_factorize(n)
ans = [1]
for p, e in pe.items():
exps = [p**ei for ei in range(1, e + 1)]
ans.extend([d * f for d in ans for f in exps])
ans.sort()
return ans
# is_prime, least_p, _, _ = sieves(2 * 10**7 + 100)
least_p = sieves(2 * 10**7 + 100)
am = [[0, 1], [1, 1]]
e2 = [[1, 0], [0, 1]]
def mat_prod(m1, m2, mod):
m2t = tuple(zip(*m2))
return [
[sum(m1ik * m2kj for m1ik, m2kj in zip(m1i, m2_j)) % mod for m2_j in m2t]
for m1i in m1
]
def mat_pow(m, p, mod):
if p == 1:
return m
mp = mat_pow(m, p // 2, mod)
mp = mat_prod(mp, mp, mod)
if p % 2:
mp = mat_prod(mp, m, mod)
return mp
def mat_pow_vec(m, p, v, mod):
if p == 0:
return v
mp = mat_pow(m, p, mod)
return [sum(mpij * vj for mpij, vj in zip(mpi, v)) % mod for mpi in mp]
def fib(n, mod):
nv = mat_pow_vec(am, n, [0, 1], mod)
return nv[0]
def test_shrink(pe, m):
ans = 1
for p, e in pe.items():
ans *= p**e
for p, e in pe.items():
for _ in range(e):
if mat_pow(am, ans // p, m) == e2:
ans //= p
else:
break
return prime_factorize(ans)
def period_p(p):
ans = 0
if p == 2:
ans = 3
elif p == 5:
ans = 20
elif pow(5, (p - 1) // 2, p) == 1:
ans = p - 1
else:
ans = 2 * (p + 1)
ans = test_shrink(prime_factorize(ans), p)
return ans
def period_pp(p, e):
p1 = period_p(p)
if e == 1:
return p1
# *= p**(e-1)
p1[p] = p1.get(p, 0) + e - 1
return p1
def period(pe):
# pisano period of Fib mod m
if not pe:
return {}
ans = {}
for p, e in pe.items():
ansi = period_pp(p, e)
for p_, e_ in ansi.items():
ans[p_] = max(ans.get(p_, 0), e_)
return ans
mod = 1_000_000_007
n = int(input())
pe = {}
for _ in range(n):
p, e = map(lambda s_: int(s_), input().split())
pe[p] = e
ans_pe = period(pe)
ans = 1
for p, e in ans_pe.items():
ans *= pow(p, e, mod)
ans %= mod
print(ans)