公式

D - XNOR Operation 解説 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 0s:

  • If you change 00 to 1, the number of 0s reduces by \(2\).
  • If you change 01 to 0, the number of 0s remains the same.
  • If you change 10 to 0, the number of 0s remains the same.
  • If you change 11 to 1, the number of 0s remains the same.

It appears that by an operation, the number of 0s either remains the same or reduces by \(2\). Therefore, it turns out that the parity of the number of 0s 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 0s. 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 0s;
  • \(S\) is not a beautiful string if it is an non-empty string containing an odd number of 0s.

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 0s, 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 0s?
  • \(\mathrm{dp}_{r,1}\): among \(S[1,r], S[2,r], \dots, S[r,r]\), how many of them contain an odd number of 0s?

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";
}

投稿日時:
最終更新: