题意有点难理解,意思就是先给你一个字符变换规则,然后求出变换后的字符串的最长回文字串。
首先这题要求我们理解manacher算法,p[i]代表什么等。我们可以在确定最长长度的时候记录位置,因为p[i]记录的是以i为中心的最长回文半径,所以就(pos±p[i]±1)/2就可以了。因为manacher会在字符串的每个字符前面上加标记,所以要/2。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<vector>
#include<cmath>
#include<map>
#include<string>
#include<queue>
#include<stack>
#include<bitset>
#include<list>
#define IO ios::sync_with_stdio(false)
#define int long long
using namespace std;
char s[200005],ns[200005<<1],c;
int len,nlen,p[200005<<1],pos;
int manacher()
{
memset(p,0,sizeof(p));
memset(ns,0,sizeof(ns));
pos=0;
ns[0]='$';
ns[1]='#';
int j=2;
for(int i=1;i<=len;i++)
{
ns[j++]=s[i];
ns[j++]='#';
}
ns[j]='\0';
nlen=j;
int maxlen=-1,id,mx=0;
for(int i=1;i<=nlen;i++)
{
if(i<mx)
{
p[i]=min(p[2*id-i],mx-i);
}
else
{
p[i]=1;
}
while(ns[i-p[i]]==ns[i+p[i]])p[i]++;
if(mx<i+p[i])
{
id=i;
mx=i+p[i];
}
if(p[i]-1>maxlen)
{
maxlen=p[i]-1;
pos=i;
}
}
return maxlen;
}
signed main()
{
IO;
while(cin>>c>>s+1)
{
int x=c-'a';
len=strlen(s+1);
for(int i=1;i<=len;i++)
{
int wei=s[i]-'a';
wei-=x;
s[i]='a'+(26+wei)%26;
}
int ans=manacher();
if(ans==1)
{
cout<<"No solution!"<<endl;
continue;
}
int xx=(pos-ans+1)/2,yy=(pos+ans-1)/2;
cout<<xx-1<<" "<<yy-1<<endl;
for(int i=xx;i<=yy;i++)
{
cout<<s[i];
}
cout<<endl;
}
}