【模板】manacher算法
题目
解析
关于回文子串问题,有很多种做法:
1,
O
(
n
3
)
O(n^3)
O(n3)
直接
O
(
n
2
)
O(n^2)
O(n2)枚举,然后
O
(
n
)
O(n)
O(n)判断
2,
O
(
n
2
)
O(n^2)
O(n2)
O
(
n
)
O(n)
O(n)枚举中点,
O
(
n
)
O(n)
O(n)扩展
3,
O
(
n
log
n
)
O(n\log n)
O(nlogn)
O
(
n
)
O(n)
O(n)枚举中点,
O
(
log
n
)
O(\log n)
O(logn)二分相等长度,哈希判相等
4,
O
(
n
)
O(n)
O(n)
枚举中点,两边扩展,更新右端点(manacher)
code(洛谷):
#include<cstdio>
using namespace std;
inline int min(int x,int y){return x<y?x:y;}
int q=1,d[22000010],ans;
char a[22000010],c;
int main()
{
a[0]='~',a[1]='|',c=getchar();
do{a[++q]=c,a[++q]='|',c=getchar();}
while(c<='z'&&c>='a');
for(int i=1,mid=0,r=0;i<=q;++i)
{
if(i<=r)d[i]=min(d[(mid<<1)-i],r-i+1);
while(a[i-d[i]]==a[i+d[i]])++d[i];
if(d[i]+i>r)r=d[i]+i-1,mid=i;
if(d[i]>ans)ans=d[i];
}
printf("%d",ans-1);
return 0;
}
code(ybtoj):
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
inline int min(int x,int y){return x<y?x:y;}
int q,d[2000010],ans,cnt;
char a[2000010],c[1000010];
int main()
{
while(1)
{
memset(d,0,sizeof(d));
cin>>c+1;
a[0]='~',a[1]='|',ans=0,q=1;
if(c[1]=='E')break;
do{a[++q]=c[q>>1],a[++q]='|';}while(c[q>>1]<='z'&&c[q>>1]>='a');
for(int i=1,mid=0,r=0;i<=q;++i)
{
if(i<=r)d[i]=min(d[(mid<<1)-i],r-i+1);
while(a[i-d[i]]==a[i+d[i]])++d[i];
if(d[i]+i>r)r=d[i]+i-1,mid=i;
if(d[i]>ans)ans=d[i];
}
if(cnt)printf("Case %d: %d\n",++cnt,ans-1);
else printf("Case %d: %d\n",++cnt,ans-2);
}
return 0;
}