結果

問題 No.3038 シャッフルの再現
ユーザー gew1fw
提出日時 2025-06-12 18:49:00
言語 PyPy3
(7.3.15)
結果
RE  
実行時間 -
コード長 1,977 bytes
コンパイル時間 166 ms
コンパイル使用メモリ 82,104 KB
実行使用メモリ 67,676 KB
最終ジャッジ日時 2025-06-12 18:49:18
合計ジャッジ時間 2,582 ms
ジャッジサーバーID
(参考情報)
judge2 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample RE * 1
other RE * 21
権限があれば一括ダウンロードができます

ソースコード

diff #

import sys
from math import gcd
from functools import reduce

MOD = 10**9 + 7

def factorize(m):
    factors = []
    i = 2
    while i * i <= m:
        if m % i == 0:
            cnt = 0
            while m % i == 0:
                cnt += 1
                m = m // i
            factors.append((i, cnt))
        i += 1
    if m > 1:
        factors.append((m, 1))
    return factors

def generate_divisors(factors):
    divisors = [1]
    for (p, exp) in factors:
        temp = []
        for d in divisors:
            current = d
            for _ in range(exp + 1):
                temp.append(current)
                current *= p
        divisors = temp
    divisors = sorted(divisors)
    return divisors

def fast_doubling(n, mod):
    if n == 0:
        return (0, 1)
    a, b = fast_doubling(n >> 1, mod)
    c = (a * (2 * b - a)) % mod
    d = (a * a + b * b) % mod
    if n & 1:
        return (d, (c + d) % mod)
    else:
        return (c, d)

def get_pisano_period(p):
    if p == 5:
        return 20
    mod5 = p % 5
    if mod5 in (1, 4):
        m = p - 1
    else:
        m = 2 * (p + 1)
    factors = factorize(m)
    divisors = generate_divisors(factors)
    for d in divisors:
        if d == 0:
            continue
        fn, fn1 = fast_doubling(d, p)
        if fn % p == 0 and fn1 % p == 1:
            return d
    return m  # Fallback, though theoretically should not reach here

def lcm(a, b):
    return a * b // gcd(a, b)

def main():
    input = sys.stdin.read().split()
    idx = 0
    N = int(input[idx])
    idx +=1
    periods = []
    for _ in range(N):
        p = int(input[idx])
        k = int(input[idx+1])
        idx +=2
        base_period = get_pisano_period(p)
        period = base_period * (p ** (k-1))
        periods.append(period)
    # Compute LCM of all periods
    if not periods:
        print(0)
        return
    total_lcm = reduce(lcm, periods)
    print(total_lcm % MOD)

if __name__ == '__main__':
    main()
0