結果
問題 |
No.2215 Slide Subset Sum
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:19:24 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 4,455 bytes |
コンパイル時間 | 908 ms |
コンパイル使用メモリ | 76,472 KB |
実行使用メモリ | 7,844 KB |
最終ジャッジ日時 | 2025-05-14 13:20:40 |
合計ジャッジ時間 | 6,404 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | -- * 2 |
other | AC * 2 TLE * 1 -- * 42 |
ソースコード
#include <iostream> #include <vector> #include <numeric> #include <stdexcept> // For potential exceptions, though not strictly needed by the final simple solution // Define the modulus const int MOD = 998244353; // Function to compute (base^exp) % mod using binary exponentiation long long power(long long base, long long exp) { long long res = 1; base %= MOD; while (exp > 0) { if (exp % 2 == 1) res = (res * base) % MOD; base = (base * base) % MOD; exp /= 2; } return res; } // Function to compute modular inverse using Fermat's Little Theorem // Assumes mod is prime and n is not a multiple of mod long long modInverse(long long n) { // Check for division by zero modulo MOD long long n_mod = n % MOD; if (n_mod < 0) n_mod += MOD; // Ensure n_mod is in [0, MOD-1] if (n_mod == 0) { // This case should ideally not happen in this problem logic unless K=1 and element=0? // Or if trying inverse logic that hits non-invertible cases. // The recompute logic avoids this issue. throw std::runtime_error("Division by zero modulo p"); } // Compute inverse using Fermat's Little Theorem: a^(p-2) = a^(-1) (mod p) for prime p return power(n_mod, MOD - 2); } int main() { // Use faster I/O operations std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); int N; // Length of the sequence A int M; // Length of the subarrays (window size) int K; // Modulo value for the sum std::cin >> N >> M >> K; std::vector<int> A(N); // Sequence A for (int i = 0; i < N; ++i) { std::cin >> A[i]; // Constraint check: 0 <= A[i] < K. This implies A[i] % K = A[i]. } // dp state vector: dp[j] stores the number of subsequences whose sum is congruent to j modulo K. // The size of the vector is K. std::vector<long long> dp(K); // Iterate through all possible starting positions k of the sliding window. // The window spans indices [k, k+M-1]. // k runs from 0 to N-M (0-based indexing). for (int k = 0; k <= N - M; ++k) { // Reset the dp state for each new window. // Initialize dp array with 0s. dp.assign(K, 0); // Base case: The empty subsequence has a sum of 0. Its count is 1. dp[0] = 1; // Process each element within the current window A[k...k+M-1]. for (int i = k; i < k + M; ++i) { // Store the current dp state because we need to read from it while updating. std::vector<long long> current_dp = dp; // Get the value of the current element A[i]. Since 0 <= A[i] < K, A[i] % K = A[i]. int x = A[i]; // Create a temporary vector to store the counts of subsequences formed by adding A[i]. // shifted_dp[j] will represent the count of subsequences from the previous state (using A[k..i-1]) // whose sum was (j - x) mod K. Adding A[i] to these results in sum j mod K. std::vector<long long> shifted_dp(K); for(int j=0; j<K; ++j) { // Calculate the index (j - x) mod K correctly, handling potential negative results. int prev_sum_idx = (j - x % K + K) % K; shifted_dp[j] = current_dp[prev_sum_idx]; } // Update the dp state for the current element A[i]. // For each remainder j, the new count dp[j] is the sum of: // 1. Subsequences from A[k...i-1] that already sum to j mod K (counts stored in current_dp[j]). These don't include A[i]. // 2. Subsequences from A[k...i-1] that sum to (j-x) mod K (counts stored in shifted_dp[j]). These subsequences now include A[i]. for (int j = 0; j < K; ++j) { dp[j] = (current_dp[j] + shifted_dp[j]) % MOD; } } // The final dp[0] contains the count of all subsequences (including the empty one) // whose sum is a multiple of K. // The problem asks for non-empty subsequences. Since the empty subsequence always has sum 0, // we subtract 1 from dp[0]. // We add MOD before taking modulo to ensure the result remains non-negative if dp[0] was 0 or 1. long long ans = (dp[0] - 1 + MOD) % MOD; // Output the answer for the current window starting at index k. std::cout << ans << "\n"; } return 0; }