BZOJ2084 [Poi2010]Antisymmetry Manachar

题目传送门 - BZOJ2084

题解

  对于一个0我们把它看作01,1看作10,然后只要原串中的某个子串可以通过这两个变换成为回文串就可以满足条件了。

  对于转换过的串,Manachar随便弄几下就可以了。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=2000005;
char s[N],_s[N],str[N];
int n,r[N];
void Manachar(char s[],int n){
	int Max=0,p=0;
	for (int i=1;i<=n;i++)
		str[i*2]=s[i],str[i*2+1]='#';
	str[0]='$',str[1]='#',str[n*2+2]='@';
	for (int i=1;i<=n*2+1;i++){
		r[i]=max(1,min(r[2*p-i],Max-i));
		while (str[i+r[i]]==str[i-r[i]])
			r[i]++;
		if (i+r[i]>Max)
			p=i,Max=i+r[i];
	}
}
int main(){
	scanf("%d",&n);
	scanf("%s",s+1);
	for (int i=1;i<=n;i++)
		if (s[i]=='0')
			_s[i*2-1]='1',_s[i*2]='0';
		else
			_s[i*2-1]='0',_s[i*2]='1';
	Manachar(_s,n*2);
	int res=0;
	for (int i=1;i<=4*n+1;i+=4)
		res+=r[i]/4;
	printf("%d",res);
	return 0;
}

  

 

posted @ 2018-03-20 21:46  zzd233  阅读(197)  评论(0编辑  收藏  举报