---
# System prepended metadata

title: '[Editorial] AB-string'

---

# [Editorial] AB-string

## Đề bài
The string $t_1t_2...t_k$ is good if each letter of this string belongs to at least one palindrome of length greater than 1.

A palindrome is a string that reads the same backward as forward. For example, the strings $A$, $BAB$, $ABBA$, $BAABBBAAB$ are palindromes, but the strings $AB$, $ABBBAA$, $BBBA$ are not.

Here are some examples of good strings:

* $t$ = $AABBB$ (letters $t_1$, $t_2$ belong to palindrome $t_1...t_2$ and letters $t_3$, $t_4$, $t_5$ belong to palindrome $t_3...t_5$ );
* $t$ = $ABAA$ (letters $t_1$, $t_2$, $t_3$ belong to palindrome $t_1...t_3$ and letter $t_4$ belongs to palindrome $t_3...t_4$ );
* $t$ = $AAAAA$ (all letters belong to palindrome $t_1...t_5$ );

You are given a string $s$ of length $n$, consisting of only letters $A$ and $B$.

You have to calculate the number of good substrings of string $s$.

[Link bài trên Codeforces](https://codeforces.com/problemset/problem/1238/D)

## Tóm tắt

Tìm số xâu con của $s$ thõa mãn: tất cả chữ cái của nó thuộc một palindrome độ dài > 1.

## Rằng buộc

$1 <= n <= 3.10^5$

## Lời giải

Thay vì tính số các xâu con thỏa mãn, ta sẽ tính số các xâu con độ dài > 1 $n (n-1)/2$ và số xâu con không thỏa mãn $bad$, khi đó thì đáp số sẽ là $n(n-1)/2 - bad$.

Xét xâu $t = t_1t_2...t_k$ , coi một chữ cái $t_i$ là "tốt" nếu nó thuộc một palindrome trong $t$.

Có thể thấy rằng tất cả chữ cái từ $t_2...t_{k-1}$ đều "tốt" vì:

* nếu $t_i = t_{i-1}$ hoặc $t_i = t_{i+1}$ thì $t_i$ thuộc palindrome độ dài = 2 (dạng $AA$ hoặc $BB$ )
* nếu $t_i \neq t_{i-1}$ và $t_i \neq t_{i+1}$ thì $t_i$ sẽ thuộc palindrome $t_{i-1}t_it_{i+1}$ (dạng $ABA$ hoặc $BAB$ )

Như vậy chỉ có chữ cái $t_1$ và $t_k$ là có thể không "tốt".

Từ đó ta có dạng của những xâu không tốt:
* $ABB...BB$
* $BB...BBA$
* $BAA...AA$
* $AA...AAB$

## Code

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

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    long long n;
    string s;
    cin >> n >> s;

    long long ans = n * (n - 1) / 2; // all substrings len >= 2
    long long bad = 0; // bad ones

    for(int times = 0; times < 2; times++) {
        long long cur = 1;
        for(int i = 1; i < n; i++) {
            if(s[i] == s[i - 1]) {
                cur++;
            } else {
                bad += cur - times; // subtract overlapping part
                cur = 1;
            }
        }
        reverse(s.begin(), s.end());
    }

    cout << ans - bad << '\n';
}
```

*Nguyễn Hoàng Dũng 2021-09-19*