• bzoj 2084: [Poi2010]Antisymmetry -- manacher


    2084: [Poi2010]Antisymmetry

    Time Limit: 10 Sec  Memory Limit: 259 MB

    Description

    对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一样,就称作“反对称”字符串。比如00001111和010101就是反对称的,1001就不是。
    现在给出一个长度为N的01字符串,求它有多少个子串是反对称的。

    Input

    第一行一个正整数N (N <= 500,000)。第二行一个长度为N的01字符串。

    Output


    一个正整数,表示反对称子串的个数。

    Sample Input

    8
    11001011

    Sample Output

    7

    hint
    7个反对称子串分别是:01(出现两次), 10(出现两次), 0101, 1100和001011

    HINT

    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 1000100
    int n,p[N],mx,md,len;
    string s;
    char c[N];
    ll ans;
    inline bool ck(int x)
    {
        if(c[x+p[x]]!=c[x-p[x]]) return (c[x+p[x]]-'0')+(c[x-p[x]]-'0')==1;
        return c[x+p[x]]=='#';
    }
    int main()
    {
        scanf("%d",&n);
        cin>>s;
        c[0]='&';
        for(int i=0;i<=n;i++)
        {
            c[i<<1|1]='#';
            c[(i<<1)+2]=s[i];
        }
        len=(n<<1)+2;
        for(int i=1;i<len;i++)
        {
            p[i]=mx>i?min(p[(md<<1)-i],mx-i):1;
            for(;ck(i);p[i]++);
            if((i&1)&&p[i]+i>mx)
            {
                mx=p[i]+i;
                md=i;
            }
            if(i&1) ans+=(p[i]-1)>>1;
        }
        printf("%lld
    ",ans);
        return 0;
    }

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    Qt BarChart实践
    Qt Charts_Audio实践
    Qt 报错LINK2019:无法解析的外部符号
    Qt Charts实践
    Qt Qwdget 汽车仪表知识点拆解8 淡入效果
    因果图法设计测试用例
    Jsoup获取部分页面数据失败 Unhandled content type. Must be text/*, application/xml, or application/xhtml+xml
    loadrunner入门篇
    如何对jmeter设置IP欺骗
    jmeter录制移动端脚本
  • 原文地址:https://www.cnblogs.com/lkhll/p/6797987.html
Copyright © 2020-2023  润新知