字符串trick

小美的01串翻转

思路

对于这种相邻字符不同的01串,一个很经典的思想,就是这种串只有两种形式 \(01010101……\) 或者 \(10101010…………\), 所以,只需要求得原字符串转换到他们的较小值就行了 ,发现枚举是 \(O(n^3)\) 的,我们采取前缀和进行优化,提前算出 \(pre[i]\) 来代表前 \(i\) 个字符与标准串的不同个数,优化到 \(O(n^2)\)

Code

点击查看代码
void solve()
{
    cin>>s;
    n=s.size();
    string s1="",s2="";
    vi p1(n+5),p2(n+5);
    for(int i=0;i<n;i++)
    {
        if(i&1)
        {
            s1+='1';
            s2+='0';
        }
        else {
            s1+='0';
            s2+='1';
        }
        p1[i+1]=p1[i]+(s1[i]!=s[i]);
        p2[i+1]=p2[i]+(s2[i]!=s[i]);
    }
    int ans=0;
    for(int len=2;len<=n;len++)
    {
        for(int l=0;l+len-1<n;l++)
        {
            int c1=0,c2=0;
            r=len+l-1;
            c1=p1[r+1]-p1[l];
            c2=p2[r+1]-p2[l];
            ans+=min(c1,c2);
        }
    }
    cout<<ans<<endl;
}
posted @ 2026-04-14 15:31  Lambda_L  阅读(1)  评论(0)    收藏  举报