C - 暗号変換と補正 / Cipher Conversion and Correction 解説 by admin
gpt-5.5-xhighOverview
For each split position \(k\), we determine whether there exists a correction sequence \(D_i\) satisfying the conditions for the encrypted values \(A_i\).
Rather than directly searching for the correction sequence, we efficiently make this determination by considering the range of possible values for each \(D_i\).
Analysis
Let us fix a split position \(k\).
Let \(X_L\) be the XOR of the first half, and \(X_R\) be the XOR of the second half. Then the transformed values \(A_i\) are determined as follows:
- When \(i < k\): \(A_i = c_i \oplus X_R\)
- When \(i \ge k\): \(A_i = c_i \oplus X_L\)
Here, \(c_i\) is the ASCII code of \(S_i\).
Next, let us consider the correction values \(D_i\).
From the conditions
\[ 97 \le A_i + D_i \le 122 \]
and
\[ D_i \ge 0 \]
each \(D_i\) must lie within a certain interval.
Specifically,
\[ D_i \ge 97 - A_i \]
but since \(D_i\) is non-negative,
\[ L_i = \max(0, 97 - A_i) \]
Also,
\[ D_i \le 122 - A_i \]
so letting
\[ U_i = 122 - A_i \]
we need
\[ L_i \le D_i \le U_i \]
Furthermore, the correction sequence is monotonically non-increasing:
\[ D_1 \ge D_2 \ge \cdots \ge D_N \]
In other words, later values must not be larger than earlier ones.
Let us consider processing from the beginning in order.
When choosing \(D_i\) at position \(i\), it cannot be larger than the previous \(D_1, \ldots, D_{i-1}\).
Also, each \(D_j\) is at most \(U_j\).
Therefore, \(D_i\) must be at most:
\[ \min(U_1, U_2, \ldots, U_i) \]
We call this limit.
At position \(i\), if
\[ L_i > \min(U_1, U_2, \ldots, U_i) \]
then it is impossible to choose \(D_i\), so that split position is infeasible.
Conversely, if for all \(i\),
\[ L_i \le \min(U_1, U_2, \ldots, U_i) \]
holds, then we can simply choose
\[ D_i = \min(U_1, U_2, \ldots, U_i) \]
This sequence is clearly monotonically non-increasing, and each \(D_i\) falls within its allowed range.
For example, suppose at a certain split position the ranges for the correction values are:
\[ [0, 22], [0, 3], [7, 32] \]
At the 3rd position, we need \(D_3 \ge 7\).
However, looking at up to the 2nd position, \(D_2 \le 3\), so by the non-increasing condition, \(D_3\) must be at most \(D_2\).
This means \(D_3 \le 3\) is required, which contradicts \(D_3 \ge 7\).
In this case, it is impossible.
If we naively enumerate all possible correction sequences \(D\), it would take exponential time since there are multiple candidates at each position.
Instead, by only managing the interval of each \(D_i\) and the minimum upper bound so far, we can determine feasibility for each split position in \(O(N)\).
Also, \(X_L, X_R\) can be computed efficiently using prefix XOR.
Let total be the XOR of the entire string, and pref[k] be the XOR of the first \(k\) characters. Then:
\[ X_L = \text{pref}[k] \]
\[ X_R = \text{total} \oplus X_L \]
Algorithm
- Convert each character to its ASCII code and store in array
c. - Build the prefix XOR array
pref.pref[i]is the XOR of the first \(i\) characters.
- For each split position \(k = 1, 2, \ldots, N-1\), do the following:
- Compute \(X_L = \text{pref}[k]\).
- Compute \(X_R = \text{pref}[N] \oplus X_L\).
- Initialize
limitto a sufficiently large value. - For each position \(i\), compute the transformed value \(A_i\).
- Determine the range of possible values for \(D_i\): $\( L_i = \max(0, 97 - A_i) \)\( \)\( U_i = 122 - A_i \)$
- Update
limit = min(limit, U_i). - If \(L_i > \text{limit}\), this split position is infeasible.
- If it never becomes infeasible through the end, count that split position as a valid split position.
- Output the answer.
Complexity
- Time complexity: \(O(N^2)\)
- Space complexity: \(O(N)\)
There are \(N-1\) split positions, and for each we check a sequence of length \(N\), so the total is \(O(N^2)\).
Since the constraint is \(N \le 5000\), this runs sufficiently fast.
Implementation Notes
Using prefix XOR, \(X_L, X_R\) for each split position can be obtained in \(O(1)\).
The range of \(D_i\) is $\( [\max(0, 97 - A_i),\ 122 - A_i] \)$
limitrepresents “the minimum of \(U_i\) up to the current position.”If
L > limitat any position, that split position is infeasible at that point.Source Code
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
string S;
cin >> N >> S;
vector<int> c(N), pref(N + 1, 0);
for (int i = 0; i < N; i++) {
c[i] = (int)S[i];
pref[i + 1] = pref[i] ^ c[i];
}
int total = pref[N];
int ans = 0;
for (int k = 1; k < N; k++) {
int XL = pref[k];
int XR = total ^ XL;
bool ok = true;
int limit = 1e9;
for (int i = 0; i < N; i++) {
int A = c[i] ^ (i < k ? XR : XL);
int L = max(0, 97 - A);
int U = 122 - A;
limit = min(limit, U);
if (L > limit) {
ok = false;
break;
}
}
if (ok) ans++;
}
cout << ans << '\n';
return 0;
}
This editorial was generated by gpt-5.5-xhigh.
投稿日時:
最終更新: