# 反对称 Antisymmetry （manacher）（hash+二分）

1：用hash加快判断，二分长度

2：用manacher的变形，改变判断条件

hash就不讲了

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#define base 10000000007
#define min(a,b) (a) > (b) ? (b) : (a)
using namespace std;
inline long long rd(){
long long x=0,f=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
return x*f;
}
inline void write(long long x){
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
return ;
}
long long n;
char a[1000006],s[1000006];
long long x[1000006],y[1000006];
long long po[1000006];
inline bool check(long long h,long long v){
if(v-h-1<0&&v==(n/2)||v+h+2>n+1&&v+1==(n/2)+1) return 0;
long long sum1=x[v]-x[v-h-1]*po[h+1];
long long sum2=y[v+1]-y[v+h+2]*po[h+1];
//cout<<h<<" "<<sum1<<" "<<sum2<<endl;
return (sum1==sum2);
}
int main(){
po[0]=1;
for(long long i=1;i<=500006;i++) po[i]=po[i-1]*base;
n=rd();
scanf("%s",a+1);
for(long long i=1;i<=n;i++){
s[i]=a[i]-'0';
x[i]=x[i-1]*base+s[i]+1;
}
for(long long i=n;i>=1;i--) y[i]=y[i+1]*base+(s[i]^1)+1;
long long ans=0;
for(long long i=1;i<n;i++){
if(s[i]!=s[i+1]) ans++;
else continue;
long long set=0;
long long l=0,r=min(i,n-i);
while(l<=r){
long long mid=(l+r)/2;
if(check(mid,i)){
l=mid+1;
set=mid;
}
else r=mid-1;
}
ans+=set;
}
write(ans);
return 0;
}

manacher是一种线性算法，用来求最长回文子串。不会的看这里：https://www.cnblogs.com/WWHHTT/p/10460258.html

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<cmath>
using namespace std;
inline long long rd(){
long long x=0,f=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
return x*f;
}
inline void write(long long x){
if(x<0) putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
return ;
}
char s[1000006];
char c[2000006];
long long n;
long long p[2000006];
int main(){
n=rd();
scanf("%s",s+1);
c[0]='\$';
for(long long i=1;i<=n;i++){
c[i*2-1]='#';
c[i*2]=s[i];
}
c[2*n+1]='#';
long long mx=0,id=0;
long long ans=0;
for(long long i=1;i<=2*n;i+=2){
if(mx>i) p[i]=min(p[2*id-i],mx-i);
else p[i]=1;
while((c[i+p[i]]==c[i-p[i]]&&c[i-p[i]]=='#')||(c[i+p[i]]=='0'&&c[i-p[i]]=='1')||(c[i-p[i]]=='0'&&c[i+p[i]]=='1')) p[i]++;
if(i+p[i]>mx) mx=i+p[i],id=i;
if(i%2) ans+=p[i]>>1;
}
/*for(long long i=1;i<=2*n;i++){
cout<<c[i]<<" ";
}
cout<<endl;
for(long long i=1;i<=2*n;i++){
cout<<p[i]<<" ";
}*/
write(ans);
return 0;
}

posted @ 2019-03-02 11:20  Bruce--Wang  阅读(246)  评论(0编辑  收藏  举报