BZOJ 2084 Poi2010 Antisymmetry Manacher
2017-07-09 12:10
399 查看
题意:
对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一样,就称作“反对称”字符串。比如00001111和010101就是反对称的,1001就不是。
现在给出一个长度为N的01字符串,求它有多少个子串是反对称的。
11001011
显然是Manacher模板题
规定“#’=‘#’ 1!=1 ,0!=0,1=0
然后就Manacher 就好了
对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一样,就称作“反对称”字符串。比如00001111和010101就是反对称的,1001就不是。
现在给出一个长度为N的01字符串,求它有多少个子串是反对称的。
Input
第一行一个正整数N (N <= 500,000)。第二行一个长度为N的01字符串。Output
一个正整数,表示反对称子串的个数。Sample Input
811001011
Sample Output
7显然是Manacher模板题
规定“#’=‘#’ 1!=1 ,0!=0,1=0
然后就Manacher 就好了
#define MAXN 500005 #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #define min(a,b) (a)<(b)?(a):(b) int len,s[MAXN<<1],p[MAXN<<1]; char ch[MAXN]; long long Ans; void Manacher(){ int id=0; for(int i=1;i<=2*len+1;i+=2){ if(p[id]+id>i)p[i]=min(p[2*id-i],p[id]+id-i); else p[i]=1; while((s[i-p[i]]==s[i+p[i]]&&s[i+p[i]]==3)||(s[i-p[i]]==0&&s[i+p[i]]==1)||(s[i-p[i]]==1&&s[i+p[i]]==0)) p[i]++; if(p[i]+i>p[id]+id)id=i; Ans+=(p[i]-1)>>1; } } int main(){ scanf("%d%s",&len,ch+1); for(int i=0;i<=len;i++)s[i*2]=ch[i]-'0',s[i*2+1]=3; s[0]=4; Manacher(); printf("%lld",Ans); }
相关文章推荐
- BZOJ 2084 [Poi2010]Antisymmetry Manacher
- bzoj2084【POI2010】Antisymmetry manacher
- 【bzoj2084】【poi2010】【Antisymmetry】【manacher】
- BZOJ[2084][Poi2010]Antisymmetry Manacher
- BZOJ 2084 [Poi2010]Antisymmetry Manacher
- 【BZOJ2084】[Poi2010]Antisymmetry【Manacher】
- BZOJ 2084: [Poi2010]Antisymmetry [Manacher]
- 【BZOJ 2084】[Poi2010]Antisymmetry manacher
- bzoj 2084: [Poi2010]Antisymmetry -- manacher
- BZOJ 2084: [Poi2010]Antisymmetry
- 【BZOJ 2084 [Poi2010]Antisymmetry 回文树
- bzoj2084【POI2010】Antisymmetry
- [BZOJ2084] [Poi2010]Antisymmetry
- bzoj 2084: [Poi2010]Antisymmetry manachar
- BZOJ2084: [Poi2010]Antisymmetry
- 【BZOJ】【2084】【POI2010】Antisymmetry
- BZOJ2084: [Poi2010]Antisymmetry
- 【BZOJ】2084: [Poi2010]Antisymmetry
- BZOJ 2084 [Poi2010]Antisymmetry
- [BZOJ2084][Poi2010]Antisymmetry 二分+hash