题目链接:D-[POI2010]ANT-Antisymmetry_牛客竞赛字符串专题班pam+manacher习题
一道板子题的小变式
思路:先观察反对称的定义--"对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一样,就称作“反对称”字符串"
先确认一点,**长度为奇数的字符串一定不可能是反对称的,因为其0和1的个数不相等,在取反之后一定与原来的不同**
先确认一点,**长度为奇数的字符串一定不可能是反对称的,因为其0和1的个数不相等,在取反之后一定与原来的不同**
现在,探究一下反对称串的性质
设原字符串s长度为4,字符为s1,s2,s3,s4,对其取反,得到1-s1,1-s2,1-s3,1-s4,将其反过来会和原串一样
即有:s1=1-s4,s2=1-s3,s3=1-s2,s4=1-s1
可以发现,s1与s4相反,s2与s3相反
所以反对称的字符串就是一种特殊的回文串,只不过(左边)=(右边取反)
考虑manacher()算法,内部有一个 while(0<=i-k-1 && i+k<n && s[i-k-1]==s[i+k]) k++;
发现,只需要把里面的==改成!=即可
最后统计所有偶数串的答案即可
即有:s1=1-s4,s2=1-s3,s3=1-s2,s4=1-s1
可以发现,s1与s4相反,s2与s3相反
所以反对称的字符串就是一种特殊的回文串,只不过(左边)=(右边取反)
考虑manacher()算法,内部有一个 while(0<=i-k-1 && i+k<n && s[i-k-1]==s[i+k]) k++;
发现,只需要把里面的==改成!=即可
最后统计所有偶数串的答案即可
tip:此题可以采用d1[],d2[]分开(即奇数串偶数串分开)的写法,个人认为更为便捷,因为这题只需要求出d2[]
代码如下
int d2[N];
//d2:以i为中心的长度为偶数的回文串个数
char s[N];
int n;
int cnt;
void manacher(){
for(int i=0,l=0,r=-1;i<n;i++){
int k=(i>r) ? 0 : min(d2[l+r-i+1],r-i+1);
while(0<=i-k-1 && i+k<n && s[i-k-1]!=s[i+k]){ //板子,这里==改成!=就行
k++;
}
d2[i]=k--;
cnt+=d2[i]; //统计个数
if(i+k>r){
l=i-k-1;
r=i+k;
}
}
return ;
}
void InfiniteLight() {
read(n);
read(s);
manacher();
println(cnt);
return ;
}

京公网安备 11010502036488号