結果
問題 | No.1357 Nada junior high school entrance examination 3rd day |
ユーザー |
![]() |
提出日時 | 2025-05-14 13:14:16 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,043 ms / 2,000 ms |
コード長 | 7,897 bytes |
コンパイル時間 | 307 ms |
コンパイル使用メモリ | 82,288 KB |
実行使用メモリ | 105,680 KB |
最終ジャッジ日時 | 2025-05-14 13:15:44 |
合計ジャッジ時間 | 15,942 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 21 |
ソースコード
import sys # Set a higher recursion depth, just in case. With iterative NTT, it might not be strictly necessary. # sys.setrecursionlimit(200000) def solve(): K = int(sys.stdin.readline()) MOD = 998244353 # The problem asks for coefficients c_0, c_1, ..., c_{2K}. # The maximum index is 2K. The total number of coefficients is 2K+1. MAX_N = 2 * K # Precomputation requires factorials up to 2K+1. # Because the polynomial A(t) has coefficients a_n = 1/(n+1)!, # for the highest degree term needed n=2K, we need a_{2K} = 1/(2K+1)!. # So we need factorials and inverse factorials up to 2K+1. MAX_FACT = MAX_N + 1 # Handle K=0 case if it were possible. The problem states K >= 1. # If K=0, MAX_N = 0, MAX_FACT = 1. The sum is empty, result is 0. Output should be just c_0=0. if K == 0: print("0") return # Precompute factorials and their modular inverses. # Size of arrays needs to be MAX_FACT + 1 to store indices 0..MAX_FACT. fact = [1] * (MAX_FACT + 1) inv_fact = [1] * (MAX_FACT + 1) for i in range(1, MAX_FACT + 1): fact[i] = (fact[i-1] * i) % MOD # Compute modular inverse using Fermat's Little Theorem for the largest factorial needed. # (MOD - 2) is the exponent for modular inverse because MOD is prime. inv_fact[MAX_FACT] = pow(fact[MAX_FACT], MOD - 2, MOD) # Compute other inverse factorials iteratively using inv_fact[i] = inv_fact[i+1] * (i+1) for i in range(MAX_FACT - 1, -1, -1): inv_fact[i] = (inv_fact[i+1] * (i+1)) % MOD # Iterative Number Theoretic Transform (NTT) # This implementation uses Cooley-Tukey Radix-2 DIT FFT algorithm adapted for modular arithmetic. def ntt(a, inv): n = len(a) if n == 1: return # Bit-reversal permutation: arrange elements in order required for iterative FFT j = 0 for i in range(1, n): rev = n >> 1 while j >= rev: j -= rev rev >>= 1 j += rev if i < j: a[i], a[j] = a[j], a[i] # Main FFT loop len_ = 2 # Current length of DFT sequences being combined while len_ <= n: # Root of unity: g=3 is primitive root for MOD 998244353 # w_len is omega_len_ = g^((MOD-1)/len_) mod MOD w_len = pow(3, (MOD - 1) // len_, MOD) if inv: # For inverse NTT, use inverse root of unity w_len = pow(w_len, MOD - 2, MOD) half_len = len_ >> 1 for i in range(0, n, len_): # Iterate through blocks of size len_ w = 1 # Current power of root of unity: omega_len_^j for j in range(half_len): # Butterfly operations u = a[i + j] # Even indexed element v = (w * a[i + j + half_len]) % MOD # Odd indexed element multiplied by root power a[i + j] = (u + v) % MOD a[i + j + half_len] = (u - v + MOD) % MOD # Ensure result is non-negative w = (w * w_len) % MOD # Update root power for next step len_ <<= 1 # Double the length for next stage if inv: # Scale by 1/n for inverse transform n_inv = pow(n, MOD - 2, MOD) for i in range(n): a[i] = (a[i] * n_inv) % MOD # Polynomial inverse computation using NTT (based on Newton-Raphson iteration) def poly_inv(A, deg): # Computes polynomial B such that A * B = 1 (mod x^deg) # Pad A to ensure it has length at least deg A_padded = A[:deg] + [0] * max(0, deg - len(A)) B = [0] * deg # Result polynomial B if deg == 0: return B # Base case: B = 1/A[0] (mod x^1) B[0] = pow(A_padded[0], MOD - 2, MOD) # Iteratively double the precision `k` k = 1 while k < deg: k *= 2 # Determine required NTT length: smallest power of 2 >= 2k # This is needed because multiplication of two polynomials of degree k-1 results in degree 2k-2. ntt_len = 1 << (2*k -1).bit_length() if k > 0 else 1 # Prepare A_k and B_k for NTT: Take required parts and pad to ntt_len # We only need A up to degree k-1 for computation mod x^k A_k = A_padded[:min(k, deg)] + [0] * (ntt_len - min(k, deg)) # Use current approximation B up to degree k-1 B_k = B[:min(k, deg)] + [0] * (ntt_len - min(k, deg)) ntt(A_k, False) ntt(B_k, False) # Compute C_ntt = NTT(A * B^2) efficiently in frequency domain # C_ntt[i] = A_k[i] * B_k[i] * B_k[i] C_ntt = [0] * ntt_len for i in range(ntt_len): C_ntt[i] = (A_k[i] * B_k[i]) % MOD C_ntt[i] = (C_ntt[i] * B_k[i]) % MOD ntt(C_ntt, True) # Inverse NTT to get coefficients of A*B^2 # Update B using the Newton-Raphson formula: B_new = 2B - A*B^2 (mod x^k) # We need to update B up to degree k-1. Copy the relevant part of B first. B_new_k = B[:k] for i in range(min(k, deg)): # Compute updates up to degree min(k, deg) - 1 term_2B = (2 * B[i]) % MOD # C_ntt holds coefficients of A*B^2. Indices correspond to powers of x. B_new_k[i] = (term_2B - C_ntt[i] + MOD) % MOD # Update B for next iteration. Store the result padded to degree `deg`. B = B_new_k + [0] * max(0, deg - k) return B[:deg] # Return the inverse polynomial up to degree deg-1 # Step 1: Define polynomial A(t) coefficients a_n = 1 / (n+1)! # We need polynomial of degree 2K, so length is 2K+1. N_poly = MAX_N + 1 A = [0] * N_poly for n in range(N_poly): # A[n] is the coefficient of t^n A[n] = inv_fact[n+1] # Access precomputed inverse factorials: 1/(n+1)! # Step 2: Compute B(t) = A(t)^(-1) mod t^(N_poly) # The coefficients b_n of B(t) are B_n / n! (where B_n are Bernoulli numbers with B1=-1/2 convention) inv_deg = N_poly # Compute inverse modulo t^(2K+1) B_coeffs = poly_inv(A, inv_deg) # Step 3: Compute the final coefficients c_i based on the derived formula # c_{2a} = (2a-1) * (-1)^(a-1) * (B_{2a} / (2a)!) * 2^(2a-1) C = [0] * (MAX_N + 1) # Result array C[0]...C[2K] # Precompute powers of 2 modulo MOD pow2 = [1] * (MAX_N + 1) for i in range(1, MAX_N + 1): pow2[i] = (pow2[i-1] * 2) % MOD # Calculate coefficients c_{2a} for a = 1 to K for a in range(1, K + 1): idx = 2*a # Index in C array corresponds to power of pi (pi^idx) # Safety check: Index should be within computed range if idx >= N_poly: continue term1 = (2*a - 1) # The factor (2a-1) term2 = 1 # The factor (-1)^(a-1) if (a - 1) % 2 == 1: # Check if a-1 is odd (i.e., a is even) term2 = MOD - 1 # Represents -1 mod P # b_{2a} = B_{2a} / (2a)! is the coefficient from poly inverse B_coeffs[idx] b_2a = B_coeffs[idx] idx_pow2 = idx - 1 # Index for power of 2 is 2a-1 # Safety check: index for power of 2 must be non-negative if idx_pow2 < 0 : continue term4 = pow2[idx_pow2] # Factor 2^(2a-1) # Combine all terms modulo MOD c_2a = (term1 % MOD * term2) % MOD c_2a = (c_2a * b_2a) % MOD c_2a = (c_2a * term4) % MOD C[idx] = c_2a # Store the computed coefficient c_{2a} at index 2a # Step 4: Print the result coefficients C[0], C[1], ..., C[2K] separated by spaces print(*(C)) solve()