BZOJ 2084 [Poi2010]Antisymmetry(manacher)

Posted forever97‘s blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 2084 [Poi2010]Antisymmetry(manacher)相关的知识,希望对你有一定的参考价值。

 

【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=2084

 

【题目大意】

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

 

【题解】

  修改manacher的判定条件,对该串进行计算即可。

 

【代码】

#include <cstdio>
#include <cstring>
using namespace std;
const int N=1000010; 
int n,m,i,r,p,f[N<<1];
long long ans;
char a[N],s[N<<1];
int min(int a,int b){return a<b?a:b;}
bool check(char x,char y){
    if(x==‘#‘&&y==‘#‘)return 1;
    if((x-‘0‘)+(y-‘0‘)==1)return 1;
    return 0;
}
void manacher(char *a){
    for(i=1;i<=n;i++)s[i<<1]=a[i],s[i<<1|1]=‘#‘;
    s[0]=‘$‘,s[1]=‘#‘,s[m=(n+1)<<1]=‘&‘;
    for(r=p=0,f[1]=1,i=1;i<m;ans+=f[i++]>>1){
        for(f[i]=r>i?min(r-i,f[p*2-i]):0;check(s[i-f[i]],s[i+f[i]]);f[i]++);
        if(i+f[i]>r)r=i+f[i],p=i;
        //printf("%d\n",f[i]); 
    }
}
int main(){
    scanf("%d",&n);
    scanf(" %s",a+1); 
    manacher(a);
    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