結果
| 問題 |
No.1978 Permutation Repetition
|
| コンテスト | |
| ユーザー |
gew1fw
|
| 提出日時 | 2025-06-12 14:06:26 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 2,866 bytes |
| コンパイル時間 | 238 ms |
| コンパイル使用メモリ | 82,696 KB |
| 実行使用メモリ | 77,056 KB |
| 最終ジャッジ日時 | 2025-06-12 14:06:32 |
| 合計ジャッジ時間 | 4,097 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 15 WA * 29 |
ソースコード
import sys
from math import gcd
from collections import defaultdict
MOD = 10**9 + 7
def main():
sys.setrecursionlimit(1 << 25)
N, M = map(int, sys.stdin.readline().split())
A = list(map(int, sys.stdin.readline().split()))
A = [a-1 for a in A]
# Step 1: Decompose A into cycles and count their lengths
visited = [False] * N
cycle_counts = defaultdict(int)
for i in range(N):
if not visited[i]:
cycle_len = 0
j = i
while not visited[j]:
visited[j] = True
j = A[j]
cycle_len += 1
cycle_counts[cycle_len] += 1
# Step 2: Factorize M and get all divisors
def get_divisors(m):
divisors = set()
for i in range(1, int(m**0.5)+1):
if m % i == 0:
divisors.add(i)
divisors.add(m//i)
return sorted(divisors)
divisors = get_divisors(M)
# Precompute factorial and inverse factorial up to N
max_n = max(cycle_counts.keys()) if cycle_counts else 0
max_fact = max(max_n, N)
fact = [1] * (max_fact + 1)
for i in range(1, max_fact + 1):
fact[i] = fact[i-1] * i % MOD
inv_fact = [1] * (max_fact + 1)
inv_fact[max_fact] = pow(fact[max_fact], MOD-2, MOD)
for i in range(max_fact-1, -1, -1):
inv_fact[i] = inv_fact[i+1] * (i+1) % MOD
# Precompute d_pows for each d and g
total = 1
for d, k in cycle_counts.items():
valid_gs = []
for g in divisors:
if (M // g) == 0:
continue
if gcd(d, M // g) != 1:
continue
valid_gs.append(g)
# Now compute the generating function's coefficient for x^k
dp = [0] * (k + 1)
dp[0] = 1
for g in valid_gs:
# Precompute d^g mod MOD
d_pow_g = pow(d, g, MOD)
# Precompute 1/g mod MOD
inv_g = pow(g, MOD-2, MOD)
# Contribution for each group of size g: (d^g / g) = d^g * inv_g mod MOD
contrib = d_pow_g * inv_g % MOD
# Iterate from high to low to avoid overwriting
for i in range(k, g-1, -1):
max_m = i // g
current_contrib = 1
for m in range(1, max_m + 1):
term = contrib * current_contrib % MOD
term = term * inv_fact[m] % MOD
prev = i - m * g
if prev < 0:
break
dp[i] = (dp[i] + dp[prev] * term) % MOD
current_contrib = current_contrib * contrib % MOD
# The coefficient is dp[k], multiply by k! to get the contribution
contribution = dp[k] * fact[k] % MOD
total = total * contribution % MOD
print(total % MOD)
if __name__ == "__main__":
main()
gew1fw