BZOJ2084 [Poi2010] Antisymmetry题解(manacher算法)

时间:2019-01-11
本文章向大家介绍BZOJ2084 [Poi2010] Antisymmetry题解(manacher算法),主要包括BZOJ2084 [Poi2010] Antisymmetry题解(manacher算法)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目:BZOJ2084.
题目大意:给定一个01串,定义0=1,00,110=1,0\neq 0,1\neq 1,问回文子串数量.

manacher裸题,重新定义一下匹配,然后每个点为对称中心最长回文子串长度,求累加和即可.不过注意只有偶数长度的串才会有贡献.

代码如下:

#include<bits/stdc++.h>
  using namespace std;
 
#define Abigail inline void
typedef long long LL;
 
const int N=500000;
 
char tmp[N*2+9];
int pal[N*2+9];
 
LL manacher(char *s,int len){
  LL ans=0;
  for (int i=1;i<=len;++i)
    tmp[i<<1]=s[i],tmp[i<<1|1]='#';
  tmp[1]='-';tmp[0]='#';
  len=len<<1|1;
  int p=0,r=0;
  for (int i=1;i<=len;i+=2){
    pal[i]=r>i?min(pal[p*2-i],r-i):1;
    while (tmp[i+pal[i]]=='#'&&tmp[i-pal[i]]=='#'||(tmp[i+pal[i]]^tmp[i-pal[i]])==1) ++pal[i];
    if (i+pal[i]>r) r=i+pal[i],p=i;
  }
  for (int i=3;i<len;i+=2) ans+=LL(pal[i]>>1);
  return ans;
}
 
char s[N+9];
int n;
 
Abigail into(){
  scanf("%d",&n);
  scanf("%s",s+1);
}
 
Abigail outo(){
  printf("%lld\n",manacher(s,n));
}
 
int main(){
  into();
  outo();
  return 0;
}