题意:n组数据,先输入26个数,代表a到z每个字母对应的价值,
然后一个字符串,求将字符串分成两个,如果是回文串这个字符串的价值是每个字母的和,不是回文串价值为0 最大价值。
如 第一组样例 ,aba ,分成两个a 和ba ,a就是一个回文串。所以价值为1;
题解求字符串的回文串前缀,和回文串后缀
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=505050;
int next[N*2];
int y[N],x[N],val[30],sum[N];
char p[N*2],s[N];
void get_next(char *p,int len)
{
int j=1;
next[0]=-1;
int k=-1;
for(;j<len;j++)
{
while(k>-1&&p[k+1]!=p[j]) k=next[k];
if(p[k+1]==p[j]) k++;
next[j]=k;
}
}
int main()
{
//freopen("Input.txt","r",stdin);
int ncase,i;
scanf("%d",&ncase);
while(ncase--)
{
for(i=0;i<26;i++)
scanf("%d",&val[i]);
scanf("%s",s);
int n=strlen(s);
if(n==1) {puts("-10000");continue;}
memset(x,0,sizeof(x));
memset(y,0,sizeof(y));
memset(p,'\0',sizeof(p));
strcpy(p,s);
sum[0]=val[p[0]-'a'];
for(i=1;i<n;i++)
sum[i]=sum[i-1]+val[p[i]-'a'];
reverse(s,s+n);p[n]='#';
strcat(p,s);
//cout<<"fist "<<p<<endl;
get_next(p,2*n+1);
int t=2*n;
while(1)
{
t=next[t];
if(t==-1) break;
x[t]=sum[t];
}
memset(p,'\0',sizeof(p));
strcpy(p,s);
sum[0]=val[p[0]-'a'];
for( i=1;i<n;i++)
sum[i]=sum[i-1]+val[p[i]-'a'];
reverse(s,s+n);p[n]='#';
strcat(p,s);
//cout<<"second "<<p<<endl;
get_next(p,2*n+1);
t=2*n;
while(1)
{
t=next[t];
if(t==-1) break;
y[t]=sum[t];
}
reverse(y,y+n);
// for(i=0;i<n;i++)
// printf("%d ",x[i]);puts("");
// for(i=0;i<n;i++)
// printf("%d ",y[i]);puts("");
int ans=x[0]+y[1];
for(i=1;i<n-1;i++)
ans=max(ans,x[i]+y[i+1]);
printf("%d\n",ans);
}
return 0;
}