bzoj 2084: [Poi2010]Antisymmetry -- manacher

Posted lkhll--qaz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",ans);
    return 0;
}

 

以上是关于bzoj 2084: [Poi2010]Antisymmetry -- manacher的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 2084: [Poi2010]Antisymmetry -- manacher

[bzoj2084] [Poi2010]Antisymmetry

BZOJ 2084 [Poi2010]Antisymmetry(manacher)

BZOJ2084: [Poi2010]Antisymmetry

bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp)

POI 2010 Antisymmetry