Title: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=6012
Analysis:
Given two strings s,t Conclusion: the subscript of the first character with different s and t is l, and the subscript of the last character is r If l==r, then there is no solution If l < R, when we flip a substring of S, we must flip s[l] and s[r] to each other Counter evidence: suppose there is a reversal method of s[l] and s[r+k], Because s[r+k]=t[r+k]=t[l], and s[l]=t[r+k], we can get s[l]=t[l], contradiction l-k is the same. So this question only needs to consider three situations: 1. Two strings are equal: palindrome substring for s 2.l==r, no solution 3. For L < R, first s[l,r] turns over and is equal to t[l,r], then find the palindrome substring centered on s[l,r], otherwise there is no solution
Ac code:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=5e6+5; int p[maxn]; ll ans; char s[maxn]; char snew[maxn]; int init(){ int len=strlen(s),j=2; snew[0]='$',snew[1]='#'; for(int i=0;i<len;i++){ snew[j++]=s[i]; snew[j++]='#'; } snew[j]='\0'; return 2*len+2; } long long manacher(){ long long res=0; int len=init(),mx=0,id; for(int i=0;i<len;i++){ if(mx>i)p[i]=min(p[2*id-i],mx-i); else p[i]=1; while(snew[i-p[i]]==snew[i+p[i]])///i-p[i] may be out of bounds. Use string to segment errors. char [] can p[i]++; if(mx<i+p[i])mx=i+p[i],id=i; res+=(long long )p[i]/2; } return res; } char s1[maxn],s2[maxn]; int main() { //ios::sync_with_stdio(0),cin.tie(0); int t; scanf("%d%*c",&t); while(t--) { scanf("%s%s",s1,s2); int len=strlen(s1); int l=0x3f3f3f3f,r=0; for(int i=0; i<len; i++) if(s1[i]!=s2[i]) { l=i; break; } for(int i=len-1;i>=0;--i) if(s1[i]!=s2[i]) { r=i; break; } if(l==r) printf("0\n"); else if(l>r){ strcpy(s,s1); printf("%lld\n",manacher()); } else if(l<r){ ans=0; string sa=s1,sb=s2; string tmp=sa.substr(l,r-l+1); reverse(tmp.begin(),tmp.end()); if(tmp==sb.substr(l,r-l+1)){ for(int i=l-1,j=r+1;i>=0&&j<sa.size();i--,++j) if(sa[i]==sa[j]) ++ans; else break; printf("%lld\n",ans+1); } else puts("0"); } } return 0; }
Finally, paste a board for the longest palindrome substring from manacher:
#include <vector> #include <iostream> #include <string> using namespace std; string Manacher(string s) { // Insert '#' string t = "$#"; for (int i = 0; i < s.size(); ++i) { t += s[i]; t += "#"; } // Process t vector<int> p(t.size(), 0);///Remember to open the array more than 2 times int mx = 0, id = 0, resLen = 0, resCenter = 0; for (int i = 1; i < t.size(); ++i) /// from 1 { p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1; while (t[i + p[i]] == t[i - p[i]]) ++p[i]; if (mx < i + p[i]) { mx = i + p[i]; id = i; } if (resLen < p[i]) ///Find the largest p[i] { resLen = p[i];///Radius of the longest palindrome substring resCenter = i;///The center of the longest palindrome substring } } ///The longest palindrome substring length len=resLen - 1; ///Rescenter - reslen / 2 return s.substr((resCenter - resLen) / 2, resLen - 1); } int main() { int n; cin>>n; string k; while(n--) { cin>>k; cout<<Manacher(k).size()<<endl; } return 0; }