リンク:
https://codeforces.com/contest/1238/problem/D
質問の意味:
この文字列の各文字が1より大きい長さの少なくとも1回文に属している場合は、文字列T1T2 ... tkが良いです。
回文は、前方と同じ後方を読み取った文字列です。たとえば、文字列A、BAB、ABBA、BAABBBAABは回文ですが、弦AB、ABBBAA、BBBAではありません。
ここでは良い文字列のいくつかの例は以下のとおりです。
T = AABBB(文字さt1、t2はT5 ... T5はT3を回文に属し、T4、T1 ... T2およびT3文字をパリンドロームに属します)。
T = ABAA(文字のT1、T2、T3は、T1 ... T3を回文に属し、文字T4はT3、T4 ...をパリンドロームに属します)。
トン= AAAAA(すべての文字は、T1 ... T5を回文に属し)。
あなたはAとBのみ文字からなる文字列の長さnのを与えられています
あなたは、文字列sの良い部分文字列の数を計算する必要があります。
アイデア:
この考察は、ABBを満たすことができない、またはbの一つだけの数を導入することができ、時間のサブストリングで左右が満たされていない、レコードが満たされていない、[保存]をクリックします。
コード:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 3e5+10;
char s[MAXN];
int n;
int main()
{
cin >> n;
cin >> (s+1);
LL cnt = 0;
for (int i = 1, j;i < n;i = j)
{
j = i;
while (j+1 <= n && s[j+1] == s[i])
j++;
i = j;
while (j+1 <= n && s[j+1] != s[i])
j++;
cnt += j-i;
}
for (int i = n, j;i > 1;i = j)
{
j = i;
while (j-1 >= 1 && s[j-1] == s[i])
j--;
i = j;
while (j-1 >= 1 && s[j-1] != s[i])
j--;
if (i-j-1 > 0)
cnt += i-j-1;
}
LL ans = (1LL*n*(n-1))/2-cnt;
cout << ans << endl;
return 0;
}