题意:
给定一个字符串,以及每个字母拥有的价值。现在要把这个字符串切成两半,如果子串是回文,那么就可以加上这个子串的字符价值之和,如果不是回文这个子串的价值就是0.
现在要求两个子串相加的最大价值。
思路:
用Manacher我们可以处理出,以某个节点ii为中心时的回文串长度, 即p[i]−1p[i]−1。
如果暴力枚举分割点,如果子串的中心的p[i]−1p[i]−1正好是子串的长度,那么说明这个子串是一个回文串。
这里由于我们要算每个字符的价值之和,可以预处理前缀和。
对于偶数长度的串和奇数长度的串分别求对应的价值。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn=500005;
int val[27],p[maxn*2],s_val[maxn];
char s[maxn],s_new[maxn*2];
int len;
//建立辅助数组
void init(){
s_new[0]='$';
s_new[1]='#';
int cnt=1;
for(;cnt<=len;cnt++){
s_new[cnt*2]=s[cnt];
s_new[cnt*2+1]='#';
}
s_new[cnt*2]='\0';
return ;
}
//马拉车算法
void manacher(){
int Len=len*2+2;
int mid=0,r=0;
for(int i=1;i<Len;i++){
if(i<r)p[i]=min(p[2*mid-i],r-i);
else p[i]=1;
while(s_new[i+p[i]]==s_new[i-p[i]])p[i]++;
if(r<i+p[i]){
r=i+p[i];
mid=i;
}
}
}
int main(){
int t,ans;
scanf("%d",&t);
while(t--){
for(int i=0;i<26;i++){
scanf("%d",&val[i]);
}
scanf("%s",s+1);
len=strlen(s+1);
//处理前缀和
for(int i=1;i<=len;i++){
s_val[i]=s_val[i-1]+val[s[i]-'a'];
}
init();//建立辅助数组
manacher();//manacher算法 求数组p[]
ans=0;
for(int i=1;i<len;i++){
int temp=0;
if(p[i+1]-1==i){//判断前i项是否是回文串
temp+=s_val[i];
}
if(p[i+len+1]-1==len-i){//判断后len-i项是否是回文串
temp+=(s_val[len]-s_val[i]);
}
ans=max(ans,temp);
}
printf("%d\n",ans);
memset(p,0,sizeof(p));
memset(s_val,0,sizeof(s_val));
}
return 0;
}
// /\ | / |**、
// / \ | / | \
// / \ |/ | / _____ ____ | /
// /------\ |\ |__/ / \ \ /\ / / \ | /
// / \ | \ | / \ \ / \ / /______\ |/
// / \ | \ | \ / \ / \ / \ |
// / \ | \ | \_____/ \/ \/ \_____ |
/**
* ┏┓ ┏┓
* ┏┛┗━━━━━━━┛┗━━━┓
* ┃ ┃
* ┃ ━ ┃
* ┃ > < ┃
* ┃ ┃
* ┃... ⌒ ... ┃
* ┃ ┃
* ┗━┓ ┏━┛
* ┃ ┃ Code is far away from bug with the animal protecting
* ┃ ┃ 神兽保佑,代码无bug
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┗━━━┓
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛
*/
// warm heart, wagging tail,and a smile just for you!
//
// _ooOoo_
// o8888888o
// 88" . "88
// (| -_- |)
// O\ = /O
// ____/`---'\____
// .' \| |// `.
// / \||| : |||// \
// / _||||| -:- |||||- \
// | | \\ - /// | |
// | \_| ''\---/'' | |
// \ .-\__ `-` ___/-. /
// ___`. .' /--.--\ `. . __
// ."" '< `.___\_<|>_/___.' >'"".
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
// \ \ `-. \_ __\ /__ _/ .-` / /
// ======`-.____`-.___\_____/___.-`____.-'======
// `=---='
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//