(事業部の定格。2)教育Codeforcesラウンド74 D. AB-文字列

リンク:

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

おすすめ

転載: www.cnblogs.com/YDDDD/p/11685968.html