結果
問題 |
No.2019 Digits Filling for All Substrings
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:04:57 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 71 ms / 2,000 ms |
コード長 | 4,813 bytes |
コンパイル時間 | 264 ms |
コンパイル使用メモリ | 82,096 KB |
実行使用メモリ | 76,020 KB |
最終ジャッジ日時 | 2025-05-14 13:06:32 |
合計ジャッジ時間 | 3,501 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 30 |
ソースコード
import sys # Function to handle the main logic def solve(): N = int(sys.stdin.readline()) S = sys.stdin.readline().strip() MOD = 998244353 # Modular exponentiation (iterative Bignum friendly) def fast_pow(base, power): """ Calculates (base^power) % MOD efficiently. """ result = 1 while power > 0: if power % 2 == 1: # If power is odd result = (result * base) % MOD # Divide power by 2 and square base base = (base * base) % MOD power //= 2 return result # Modular inverse using Fermat's Little Theorem # Requires MOD to be a prime number, which 998244353 is. def inverse(a): """ Calculates modular multiplicative inverse of a under modulo MOD. """ return fast_pow(a, MOD - 2) # Precompute modular inverses needed inv3 = inverse(3) # Modular inverse of 3 inv10 = inverse(10) # Modular inverse of 10 # Precompute powers of 10 and inverse 10 modulo MOD # P10[k] stores 10^k % MOD # InvP10[k] stores (10^{-1})^k % MOD P10 = [1] * (N + 1) InvP10 = [1] * (N + 1) for i in range(1, N + 1): P10[i] = (P10[i-1] * 10) % MOD InvP10[i] = (InvP10[i-1] * inv10) % MOD # Compute prefix sums D and Q # D[i]: Stores the sum of fixed digits modulo 3 in the prefix S[0...i-1]. # '?' are treated as contributing 0 to this sum. # Q[i]: Stores the count of '?' characters in the prefix S[0...i-1]. D = [0] * (N + 1) Q = [0] * (N + 1) for i in range(N): # Calculate D[i+1] based on D[i] and S[i] D[i+1] = D[i] # Initialize with previous prefix sum if S[i] != '?': # If it's a digit, add its value to the sum modulo 3 D[i+1] = (D[i] + int(S[i])) % 3 # Calculate Q[i+1] based on Q[i] and S[i] Q[i+1] = Q[i] # Initialize with previous prefix count if S[i] == '?': # If it's a '?', increment the count Q[i+1] += 1 # Initialize cumulative sums P1 and P2 which form the total answer # P1 corresponds to the sum part involving powers of 10 # P2 corresponds to the sum part involving the delta function based on remainders P1 = 0 P2 = 0 # CurrentSumInvP10 stores the sum: sum_{i=0}^{R-1} InvP10[Q[i]] % MOD # This is needed to calculate P1 efficiently. CurrentSumInvP10 = 0 # counts[r] stores the count of indices i in {0, ..., R-1} # such that D[i] % 3 == r. This is needed for P2. counts = [0] * 3 # Initialize counts array based on the empty prefix (index 0). # D[0] = 0, so the count for remainder 0 starts at 1. counts[0] = 1 # Iterate over all possible right endpoints R of substrings S[L:R] (1-based index) for R in range(1, N + 1): # === Part 1: Calculation related to P1 === # Update the running sum of inverse powers of 10 based on Q values # Add the term corresponding to prefix ending at index R-1 (0-based index L-1 = R-1) CurrentSumInvP10 = (CurrentSumInvP10 + InvP10[Q[R-1]]) % MOD # Calculate Term1 for endpoint R. Term1 is P10[Q[R]] * CurrentSumInvP10 # This corresponds to sum_{L=1..R} P10[Q[R] - Q[L-1]] Term1 = (P10[Q[R]] * CurrentSumInvP10) % MOD # Accumulate Term1 into P1 P1 = (P1 + Term1) % MOD # === Part 2: Calculation related to P2 === # Calculate Term2 for endpoint R. Term2 is related to sum_{L=1..R} delta(D[L-1], D[R]) target_rem = D[R] # D[R] is already modulo 3 # Get the count of prefix sums D[i] (for i < R) having the same remainder as D[R] count_target_rem = counts[target_rem] # Calculate Term2 = (3 * count - R) mod MOD. # The formula is derived from properties of the delta function. Term2 = (3 * count_target_rem - R) % MOD # Accumulate Term2 into P2. Add MOD before taking modulo to handle potential negative values. P2 = (P2 + Term2 + MOD) % MOD # === Update state for the next iteration (R+1) === # The counts array needs to be updated to include the contribution of index R. # Increment the count for the remainder D[R] % 3. counts[D[R]] += 1 # This update prepares counts for the next iteration R+1 # No need for MOD here as counts are simple integers. # === Final Calculation === # The total sum is derived from P1 and P2: Sum = (P1 + P2) * inv3 mod MOD TotalSum = (P1 + P2 + MOD) % MOD # Ensure P1+P2 is non-negative before multiplying by inv3 FinalAns = (TotalSum * inv3) % MOD # Print the final answer print(FinalAns) # Execute the solver function solve()