D - XNOR Operation Editorial by en_translator
First, consider the condition where a string \(S\) is a beautiful string.
When it comes to a problem like this, where you perform operations against strings or sequences, it is often effective to look for an invariant (which remains constant by any operation).
We observe the operation from this viewpoint. Let us track the number of 0
s:
- If you change
00
to1
, the number of0
s reduces by \(2\). - If you change
01
to0
, the number of0
s remains the same. - If you change
10
to0
, the number of0
s remains the same. - If you change
11
to1
, the number of0
s remains the same.
It appears that by an operation, the number of 0
s either remains the same or reduces by \(2\). Therefore, it turns out that the parity of the number of 0
s is invariant under the operation.
In order for \(S\) to be a beautiful string, it must finally become \(S=\) 1
, which contains an even number of 0
s. Based on the invariant above, we can prove that
- \(S\) is a beautiful string if it is an non-empty string containing an even number of
0
s; - \(S\) is not a beautiful string if it is an non-empty string containing an odd number of
0
s.
Thus, the condition for being a beautiful string has been rephrased to a form suitable for counting.
Next, let us count the number of beautiful strings, or strings that contain an even number of 0
s, contained in \(T\) as a substrings.
Let \(S[i,j]\) denote the string formed by the \(i\)-th through \(j\)-th characters of \(S\). Define the states of a DP (Dynamic Programming) as follows:
- \(\mathrm{dp}_{r,0}\): among \(S[1,r], S[2,r], \dots, S[r,r]\), how many of them contain an even number of
0
s? - \(\mathrm{dp}_{r,1}\): among \(S[1,r], S[2,r], \dots, S[r,r]\), how many of them contain an odd number of
0
s?
According to this definition, the values \(\mathrm{dp}_{r,0}\) and \(\mathrm{dp}_{r,1}\) and the character \(S_{r+1}\) allow us to compute \(\mathrm{dp}_{r+1,0}, \mathrm{dp}_{r+1,1}\). The answer to the original problem is \(\sum_{r=1}^N \mathrm{dp}_{r,0}\).
Hence, the problem can be solved in \(\mathrm{O}(N)\) time, which is fast enough.
- Sample code (C++)
#include <iostream>
#include <string>
using namespace std;
constexpr int nmax = 2e5 + 10;
int dp[nmax][2];
int main() {
int N;
string S;
cin >> N >> S;
for (int r = 1; r <= N; r++) {
if (S[r - 1] == '0') {
dp[r][0] = dp[r - 1][1];
dp[r][1] = dp[r - 1][0] + 1;
} else {
dp[r][0] = dp[r - 1][0] + 1;
dp[r][1] = dp[r - 1][1];
}
}
long long ans = 0;
for (int r = 1; r <= N; r++) ans += dp[r][0];
cout << ans << "\n";
}
posted:
last update: