結果
| 問題 |
No.958 たぷりすたべる (回文)
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 2025-05-14 13:18:18 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 6,682 bytes |
| コンパイル時間 | 810 ms |
| コンパイル使用メモリ | 78,688 KB |
| 実行使用メモリ | 7,844 KB |
| 最終ジャッジ日時 | 2025-05-14 13:19:10 |
| 合計ジャッジ時間 | 5,005 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 39 WA * 14 |
ソースコード
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
// Function to compute Manacher's algorithm results for odd length palindromes
// s: input string (1-based indexing is expected by the implementation)
// n: length of s
// returns: vector P where P[i] is the radius of the maximal odd palindrome centered at index i.
// The length of the palindrome centered at i is 2*P[i] + 1.
std::vector<int> manacher_odd(const std::string& s, int n) {
// P[i] stores the radius k. The palindrome is s[i-k..i+k].
// Initialize radius vector P with size n+1 (for 1-based indexing) with all zeros.
std::vector<int> P(n + 1, 0);
// l, r define the boundaries of the palindrome that extends furthest to the right.
// Initially, the range [l, r] is empty, representing no palindrome found yet.
// Using [1, 0] ensures the first center i=1 is not considered within r.
int l = 1, r = 0;
// Iterate through all possible centers i from 1 to n
for (int i = 1; i <= n; ++i) {
int k = 0; // Initialize radius k for center i
// If center i is within the current rightmost palindrome [l, r]
if (i <= r) {
// Calculate the mirror index of i with respect to the center of the [l, r] palindrome.
// The center is (l+r)/2. The mirror index is l + r - i.
// We can leverage the already computed radius P[mirror].
// The radius at i, k, is at least min(P[mirror], distance from i to the right boundary r).
k = std::min(P[l + r - i], r - i);
}
// Attempt to expand the palindrome centered at i, starting from radius k.
// Check characters symmetrically around i: s[i - (k+1)] and s[i + (k+1)].
// Loop continues as long as indices are within bounds [1, n] and characters match.
while (i - k - 1 >= 1 && i + k + 1 <= n && s[i - k - 1] == s[i + k + 1]) {
k++; // Increase radius if characters match
}
P[i] = k; // Store the final computed radius for center i
// If the palindrome centered at i [i-k, i+k] expands beyond the current rightmost boundary r,
// update l and r to the boundaries of this new rightmost palindrome.
if (i + k > r) {
l = i - k; // New left boundary
r = i + k; // New right boundary
}
}
return P; // Return the computed radii vector
}
int main() {
// Use fast I/O operations
std::ios_base::sync_with_stdio(false);
std::cin.tie(NULL);
long long N_ll; // Use long long for N to potentially compute N*K without overflow
long long K; // K can be large
int Q; // Number of queries
std::cin >> N_ll >> K >> Q;
int N = static_cast<int>(N_ll); // N itself fits within int based on constraints (<= 2*10^5)
std::string S_orig; // The base string S
std::cin >> S_orig;
// Handle the edge case N=0, though constraints state N >= 1.
// If N were 0, T would be empty. Any query x would be invalid or trivial.
// Given N >= 1, this check is technically not needed but safe.
if (N == 0) {
for (int i = 0; i < Q; ++i) {
long long x;
std::cin >> x; // Read the query position to consume input
std::cout << 1 << "\n"; // An empty string conceptually might have a point center palindrome of length 1? Or 0? Sample behavior suggests 1.
}
return 0;
}
// Create S' = S + S. Manacher requires 1-based indexing.
// Prepend a dummy character (space) to make the string 1-indexed.
std::string S_doubled = S_orig + S_orig;
std::string S_doubled_1based = " " + S_doubled;
int N_doubled = 2 * N; // Length of S'
// Compute Manacher radii P' for S' using the implemented function
std::vector<int> P_doubled = manacher_odd(S_doubled_1based, N_doubled);
// Precompute the structural radii R[p] for each potential center p in S (p = 1..N)
// R[p] represents the radius of the maximal palindrome centered at p in the infinite string T_infinity = SSS...
std::vector<long long> R(N + 1);
for (int p = 1; p <= N; ++p) {
long long r1 = P_doubled[p]; // Radius centered at p in S'
long long r2 = P_doubled[p + N]; // Radius centered at p+N (corresponding position in the second S) in S'
// Condition for infinite structural radius:
// Derived from the observation that if the palindromes centered at p and p+N in S'
// "connect" or "overlap" sufficiently, the pattern repeats infinitely.
// The condition r1 + r2 >= N - 1 captures this.
if (r1 + r2 >= N - 1) {
R[p] = -1; // Use -1 as a sentinel value to signify infinite radius
} else {
// If the structural radius is finite, it's determined by the palindrome centered at p within S'.
// The radius cannot exceed what's computed by Manacher on S'.
R[p] = r1;
}
}
// Process each query
for (int i = 0; i < Q; ++i) {
long long x; // Query position x can be large (up to KN)
std::cin >> x;
// Map the query position x in T to the corresponding position p in the base string S (1-based).
// The modulo arithmetic finds the position within a block of S.
int p = (x - 1) % N + 1;
long long R_p = R[p]; // Fetch the precomputed structural radius for position p
// Calculate the boundary limit R_max. This is the maximum possible radius centered at x
// constrained by the boundaries of the full string T (length KN).
// R_max = min(distance to left end T[1], distance to right end T[KN]).
long long KN = K * N_ll; // Total length of T. Use N_ll (long long N) for calculation.
long long R_max = std::min(x - 1, KN - x); // Both distances x-1 and KN-x must be non-negative.
long long final_r; // The final maximal radius for the palindrome centered at x in T
if (R_p == -1) { // Case 1: Structural radius is infinite
final_r = R_max; // The radius is limited only by the boundaries of T.
} else { // Case 2: Structural radius R_p is finite
final_r = std::min(R_p, R_max); // The radius is limited by both the structure (R_p) and boundaries (R_max).
}
// The length of an odd palindrome with radius final_r is 2 * final_r + 1.
long long length = 2 * final_r + 1;
std::cout << length << "\n"; // Output the computed length
}
return 0; // Indicate successful execution
}
qwewe