CodeForces 1238D AB-string

cf questions surface

Problem-solving ideas

During the race did not seem to be the idea, so after the game, the group shared approach also did not understand ...... month after the official explanations by today finally put up the title.

You can use the indirect method, the total number of sub-string minus the number of poor sub-sub-string is a good number of strings. Not a good substring cover the four -

  • ABB ... BB
  • Baa ... aaaa
  • AA ... AAB
  • BB ... BBA

Other cases are good substring. Proof enough words to talk about classified

  • Bad letters intermediate substring
    • The letter about the letters are equal
  • Bad letters substring edge
    • If there is another letter of the alphabet and the same substring

The official said so solution to a problem -

Let's call a character \(t_i\) in string \(t_1t_2…t_k\) is bad if there is no such palindrome \(t_lt_{l+1}…t_r\) that \(l\leqslant i\leqslant r\). Any character in substring \(t_2t_3…t_{k−1}\) is good. It can be proven as follows. If \(t_i=t_i+1\) or \(t_i=t_i−1\) then \(t_i\) belong to a palindrome of length 2. If \(t_i\not = t_{i+1}\) and \(t_i≠t_{i−1}\) then \(t_i\) belong to a palindrome \(t_{i−1}…t_{i+1}\).

So only characters \(t1\) and \(tk\) can be bad. But at the same time character \(t1\) is bad if there is no character \(ti\) such that \(i>1\) and \(t_i=t_1\). It is true because substring \(t_1t_2…t_i\) is palindrome (index \(i\) is minimum index such that \(t_i=t_1\)).

So, there are only 4 patterns of bad strings:

  1. ABB…BBABB…BB;
  2. BAA…AABAA…AA;
  3. AA…AABAA…AAB;
  4. BB…BBABB…BBA;

All that remains is to count the number of substrings of this kind.

源代码

写的有点丑,本来可以一个循环完事的。

#include<cstdio>

long long n;
char s[300005];
int cnt[300005]={1},seg;
long long ans;
int main()
{
    scanf("%lld",&n);
    scanf("%s",s);
    int pos=0;
    for(int i=1;i<n;i++)
    {
        if(s[i]==s[pos]) cnt[seg]++;
        else
        {
            seg++;
            cnt[seg]=1;
            pos=i;
        }
    }
    //for(int i=0;i<=seg;i++) printf("%d ",cnt[i]);
    ans=n*(n-1)>>1;
    for(int i=1;i<=seg;i++)// cnt[i] and cnt[i-1]
    {
        ans-=cnt[i-1]+cnt[i]-1;
    }
    printf("\n%lld\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/wawcac-blog/p/11806855.html
Recommended