結果
| 問題 |
No.2019 Digits Filling for All Substrings
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 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()
qwewe