結果

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

ソースコード

diff #

import sys
import math

MOD = 10**9 + 7

def matrix_mult(a, b, mod):
    return [
        [(a[0][0]*b[0][0] + a[0][1]*b[1][0]) % mod,
         (a[0][0]*b[0][1] + a[0][1]*b[1][1]) % mod],
        [(a[1][0]*b[0][0] + a[1][1]*b[1][0]) % mod,
         (a[1][0]*b[0][1] + a[1][1]*b[1][1]) % mod]
    ]

def matrix_pow(mat, power, mod):
    result = [[1, 0], [0, 1]]  # Identity matrix
    while power > 0:
        if power % 2 == 1:
            result = matrix_mult(result, mat, mod)
        mat = matrix_mult(mat, mat, mod)
        power //= 2
    return result

def factorize(n):
    factors = {}
    while n % 2 == 0:
        factors[2] = factors.get(2, 0) + 1
        n //= 2
    i = 3
    while i * i <= n:
        while n % i == 0:
            factors[i] = factors.get(i, 0) + 1
            n //= i
        i += 2
    if n > 1:
        factors[n] = 1
    return factors

def get_divisors_sorted(factors):
    divisors = [1]
    for p in factors:
        exponents = [p**e for e in range(1, factors[p]+1)]
        new_divisors = []
        for d in divisors:
            for exp in exponents:
                new_divisors.append(d * exp)
        divisors += new_divisors
    divisors = list(set(divisors))
    divisors.sort()
    return divisors

def compute_pisano_prime(p):
    if p == 2:
        return 3
    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 = get_divisors_sorted(factors)
    for d in divisors:
        if d == 0:
            continue
        mat = matrix_pow([[1, 1], [1, 0]], d, p)
        fd = mat[0][1]
        fd1 = mat[0][0]
        if fd % p == 0 and fd1 % p == 1:
            return d
    return m  # should not reach here

def compute_pisano_prime_power(p, k):
    if p == 2:
        if k == 1:
            return 3
        else:
            return 3 * (2 ** (k - 1))
    if p == 5:
        if k == 1:
            return 20
        else:
            return 20 * (5 ** (k - 1))
    base_period = compute_pisano_prime(p)
    return base_period * (p ** (k - 1))

def lcm(a, b):
    return a * b // math.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
        pp = compute_pisano_prime_power(p, k)
        periods.append(pp)
    current_lcm = 1
    for p in periods:
        current_lcm = lcm(current_lcm, p)
        current_lcm %= MOD  # To prevent integer overflow, though in Python it's not an issue
    print(current_lcm % MOD)

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