版权声明:转载请注明原出处啦QAQ(虽然应该也没人转载): https://blog.csdn.net/hzk_cpp/article/details/86410026
题目:POJ3974.
题目大意:给定一个字符串,求它的最长回文子串.
一看是道manacher的裸题,于是可以拿来manacher练手.
但是既然在蓝书上说可以用hash解决,那就当get一个新技能写个hash吧(虽然在考场上时间不够了manacher也比二分+hash好写…).
大概就是说我们枚举对称中心,然后二分一下最长可以向两边拓展的长度,然后暴力判定两边是否相等.这就可以想到正着预处理一遍hash值,反着预处理一遍hash值来做到 判定.
二分+hash代码如下:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define Abigail inline void
typedef long long LL;
typedef unsigned long long ULL;
const int N=2000000;
const ULL P=131;
char c[N+9];
int n,cas,ans;
ULL s1[N+9],s2[N+9],Pow[N+9];
ULL Hash(ULL *s,int l,int r){return s[r]-s[l-1]*Pow[r-l+1];}
ULL reHash(ULL *s,int l,int r){return s[l]-s[r+1]*Pow[r-l+1];}
bool check(int mid,int len){
if (mid-len<0||mid+len-1>n) return false;
return Hash(s1,mid-len+1,mid)==reHash(s2,mid,mid+len-1);
}
int solve(int mid){
int len=0;
for (int i=19;i>=0;--i)
if (check(mid,len+(1<<i))) len+=1<<i;
return len;
}
Abigail start(){
ans=0;
n=strlen(c+1);
c[0]='^';
for (int i=n;i>=1;--i)
c[i<<1|1]='#',c[i<<1]=c[i];
c[1]='#';
n=n<<1|1;
Pow[0]=1;
for (int i=1;i<=n;++i)
Pow[i]=Pow[i-1]*P;
for (int i=1;i<=n;++i)
s1[i]=s1[i-1]*P+c[i];
for (int i=n;i>=1;--i)
s2[i]=s2[i+1]*P+c[i];
}
Abigail work(){
for (int i=1;i<=n;++i)
ans=max(ans,solve(i)-1);
}
Abigail outo(){
printf("Case %d: %d\n",cas,ans);
}
int main(){
while (~scanf("%s",c+1)&&c[1]^'E'){
++cas;
start();
work();
outo();
}
return 0;
}
manacher代码如下:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define Abigail inline void
typedef long long LL;
typedef unsigned long long ULL;
const int N=2000000;
char tmp[N+9];
int pal[N+9];
int manacher(char *c,int n){
for (int i=1;i<=n;++i)
tmp[i<<1]=c[i],tmp[i<<1|1]='#';
tmp[0]='^';tmp[1]='#';
n=n<<1|1;
int p=0,r=0,ans=0;
for (int i=1;i<=n;++i){
pal[i]=r>i?min(pal[2*p-i],r-i):1;
while (tmp[i+pal[i]]==tmp[i-pal[i]]) ++pal[i];
if (i+pal[i]>r) r=i+pal[i],p=i;
ans=max(ans,pal[i]);
}
return ans-1;
}
char c[N+9];
int n,ans,cas;
Abigail work(){
n=strlen(c+1);
ans=manacher(c,n);
}
Abigail outo(){
printf("Case %d: %d\n",cas,ans);
}
int main(){
while (~scanf("%s",c+1)&&c[1]^'E'){
++cas;
work();
outo();
}
return 0;
}