CodeForces 1238D AB-string

烂漫一生 提交于 2019-12-03 20:22:46

cf题面

解题思路

比赛过程中好像完全没有想法来着,打完比赛,群里分享的做法也并没有看懂……一个月后的今天终于靠官方题解把题补了。

可以用间接法,总的子串数量减去不好的子串数量就是好的子串数量。而不好的子串就4种——

  • ABB...BB
  • BAA...AA
  • AA...AAB
  • BB...BBA

其他情况都是好的子串。证明的话分类讨论一下就好

  • 不好的字母在子串中间
    • 该字母左右的字母是否相等
  • 不好的字母在子串边上
    • 子串中是否存在另一个和该字母相同的字母

官方题解这么说的——

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;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!