题解 P3501 【[POI2010]ANT-Antisymmetry】
题意描述
一句话描述:对于一个0/1序列,求出其中异或意义下回文的子串数量。
题解
我们可以看出,这个其实是一个对于异或意义下的回文子串数量的统计,什么是异或意义下呢?平常,我们对回文的定义是,对于任意
那么,我们可以尝试使用Manache算法来解决。当然,编程时,我们并不必真的去把0/1序列转换为数字序列,进行异或操作,这样会给自己增加一波常数(迷),我们构造一个to数组,
对于Manache算法有任何不了解的地方,可以戳!!!这里!!!,又看不懂的地方,也可以联系文文
最后推一波自己博客(逃
对于代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
const int maxn = 1000010;
typedef unsigned long long ull;
char SS1[maxn],S[maxn],to[500];
int n,len[maxn],tot=1;
int main() {
scanf("%d%s",&n,SS1+1);S[0]='$',S[1]='#';
for(register int i=1;i<=n;++i) S[++tot]=SS1[i],S[++tot]='#';
to['1']='0',to['0']='1',to['#']='#',to['$']='$';
int pos=1,mx=1;ull ans=0;
for(register int i=1;i<=tot;i+=2) {
len[i]=(i<mx?std::min(mx-i,len[(pos<<1)-i]):1);
while(S[i+len[i]]==to[S[i-len[i]]]) len[i]++;
if(len[i]+i>mx) {
mx=len[i]+i;pos=i;
}
ans+=len[i]>>1;
}
printf("%llu\n",ans);
return 0;
}