题目链接:
https://hihocoder.com/problemset/problem/1032?sid=868170
最长回文子串
3
abababa
aaaabaa
acacdas
sample output
7
5
3
题解
Manacher算法求解最长回文子串
最后答案为max(P[i]-1)
代码
#include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<ctime> #include<vector> #include<cstdio> #include<string> #include<bitset> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<functional> using namespace std; #define X first #define Y second #define mkp make_pair #define lson (o<<1) #define rson ((o<<1)|1) #define mid (l+(r-l)/2) #define sz() size() #define pb(v) push_back(v) #define all(o) (o).begin(),(o).end() #define clr(a,v) memset(a,v,sizeof(a)) #define bug(a) cout<<#a<<" = "<<a<<endl #define rep(i,a,b) for(int i=a;i<(b);i++) #define scf scanf #define prf printf typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; typedef vector<pair<int,int> > VPII; const int INF=0x3f3f3f3f; const LL INFL=0x3f3f3f3f3f3f3f3fLL; const double eps=1e-8; const double PI = acos(-1.0); //start---------------------------------------------------------------------- const int maxn=2e6+10; char s[maxn]; //P[i]表示把回文串折叠起来的长度 //mx表示当前计算出来的回文串往右延伸的最远端 //d表示贡献出mx的串的回文中心 int P[maxn],mx,id,n; int solve(){ int ret=1; int len=strlen(s+1); n=len*2+1; s[0]='$',s[n]='#',s[n+1]='\0'; for(int i=len*2;i>=1;i--){ if(i&1) s[i]='#'; else s[i]=s[i/2]; } mx=1,id=0; for(int i=1;i<=n;i++){ //优化的核心,画画图比较好理解,j=2*id-i表示i关于id对称的点 P[i]=mx>i?min(mx-i,P[2*id-i]):1; int k=i+P[i]; while(s[k]==s[2*i-k]) k++,P[i]++; if(k>mx){ mx=k; id=i; } ret=max(ret,P[i]-1); } return ret; } int main() { int tc; scf("%d",&tc); while(tc--){ scf("%s",s+1); int ans=solve(); prf("%d\n",ans); } return 0; } //end-----------------------------------------------------------------------
来源:https://www.cnblogs.com/fenice/p/5844217.html