Official

F - Not Adjacent Editorial by en_translator


Let \(|S|\) denote the length of \(S\), and \(S_i\) the \(i\)-th character of \(S\).

If \(S_i\neq S_{i+1}\) for all \(i\), then all strings satisfy the conditon, so the sought count is \(\frac{|S|(|S|+1)}{2}\). (There is a one-to-one correspondence between a way to choose two partitions among the \((|S| + 1)\) partitions including the beginning and the end, and the substring between the two partitions.)

 If S = abac

  |a|b|a|c|
  ^ ^ ^ ^ ^  ← Choosing two out of these five corresponds one-to-one to a substring

If there is a position where \(S_i=S_{i+1}\), we cannot choose \(i\) and \((i+1)\) simultaneously. Therefore, the answer is obtained by splitting the string between the \(i\)-th and \((i+1)\)-th string, evaluating the count for each block, and finding the sum.

 If S = abbcabcbaaabc
    ab|bcabcba|a|abc
    3 +  28 + 1 + 6 = 38

Since there are \(\frac{|S|(|S|+1)}{2}\) substrings of \(S\), the answer is at most \(\frac{|S|(|S|+1)}{2}\), which fits in a 64-bit integer type; it is sufficient to take modulus only once at the end.

Hence, the problem has been solved in a total of \(O(|S|)\) time.

Sample code (C++)

#include<bits/stdc++.h>
using namespace std;

int main(){
  string s;
  cin >> s;

  long long ans = 0;
  int start_i = 0;
  for(int i=0; i<s.size(); i++){
    if(i+1 == s.size() || s[i] == s[i+1]){
      ans += (long long) (i - start_i + 1) * (i - start_i + 2) / 2;
      start_i = i + 1;
    }
  }
  cout << ans % 998244353 << endl;
}

Sample code (Python)

S = input()
start_i = 0
ans = 0
for i, c in enumerate(S):
  if i+1 == len(S) or S[i+1] == c:
    ans += (i - start_i + 1) * (i - start_i + 2) // 2
    start_i = i + 1
print(ans % 998244353)

posted:
last update: