結果
問題 |
No.1080 Strange Squared Score Sum
|
ユーザー |
![]() |
提出日時 | 2025-05-14 12:56:12 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 3,161 bytes |
コンパイル時間 | 313 ms |
コンパイル使用メモリ | 82,240 KB |
実行使用メモリ | 56,396 KB |
最終ジャッジ日時 | 2025-05-14 12:58:03 |
合計ジャッジ時間 | 7,416 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | TLE * 1 -- * 19 |
ソースコード
MOD = 10**9 + 9 def main(): import sys N, = map(int, sys.stdin.read().split()) # Precompute factorial and inverse factorial modulo MOD fact = [1] * (N + 1) for i in range(1, N + 1): fact[i] = fact[i-1] * i % MOD inv_fact = [1] * (N + 1) inv_fact[N] = pow(fact[N], MOD-2, MOD) for i in range(N-1, -1, -1): inv_fact[i] = inv_fact[i+1] * (i+1) % MOD # Find a square root of -1 mod MOD using the fact that MOD ≡ 1 mod 4 # Using Tonelli-Shanks algorithm to find sqrt(-1) def tonelli_shanks(n, p): if pow(n, (p-1)//2, p) != 1: return None Q = p - 1 S = 0 while Q % 2 == 0: Q //= 2 S += 1 z = 2 while pow(z, (p-1)//2, p) != p-1: z += 1 c = pow(z, Q, p) x = pow(n, (Q+1)//2, p) t = pow(n, Q, p) m = S while t != 1: i, temp = 0, t while temp != 1 and i < m: temp = pow(temp, 2, p) i += 1 if i == m: return None b = pow(c, 1 << (m - i - 1), p) x = x * b % p t = t * b * b % p c = b * b % p m = i return x sqrt_neg_1 = tonelli_shanks(MOD-1, MOD) i = sqrt_neg_1 # Compute f(x) = sum_{a=1 to N} (a+1)^2 x^a f_coeff = [0] * (N+1) for a in range(1, N+1): if a > N: break val = (a + 1) * (a + 1) % MOD f_coeff[a] = val # Compute H(x) = cos(f(x)) + sin(f(x)) mod x^{N+1} # Using the series expansion up to terms that contribute to x^N # H(x) = sum_{m=0 to N} [ (-1)^{floor(m/2)} * f(x)^m / m! ] H = [0] * (N+1) H[0] = 1 # Initial term for m=0 # Precompute the powers of f(x) using dynamic programming # dp[m][k] is the coefficient of x^k in f(x)^m # Instead, we use a rolling approach from collections import defaultdict current_pows = [0]*(N+1) current_pows[0] = 1 # f^0 is 1 for m in range(1, N+1): next_pow = [0]*(N+1) # Multiply current_pows by f_coeff for k in range(N+1): if current_pows[k] == 0: continue for a in range(1, N+1): if k + a > N: break next_pow[k+a] = (next_pow[k+a] + current_pows[k] * f_coeff[a]) % MOD current_pows = next_pow # Determine the sign: (-1)^{floor(m/2)} sign = -1 if (m // 2) % 2 else 1 if m % 2 == 1: sign *= (-1 if (m//2) % 2 else 1) sign = (-1) ** (m // 2) if m % 2 == 1: sign *= 1 # Add to H with division by m! inv_m_fact = inv_fact[m] term = sign * inv_m_fact % MOD for k in range(N+1): if k > N: break contrib = current_pows[k] * term % MOD H[k] = (H[k] + contrib) % MOD # Multiply by N! and handle modulo N_fact = fact[N] for K in range(1, N+1): res = H[K] * N_fact % MOD print(res) if __name__ == '__main__': main()