小明最近在玩一种关于字符串的游戏,在这个游戏中,所有的字符串都是有小写英文字母(a-z)组成的。游戏中规定了每个字母的价值,这个价值用一个绝对值不超过100的整数表示(可以为正也可以为负)。一个字符串的价值等于构成这个字符串的所有字母的价值之和。比如,a的价值为-1,b的价值为0,c的价值为1时,字符串aabc的价值就是:(-1) + (-1) + 0 + 1 = -1。游戏的目标是,给定一个长度不超过500000的字符串,求这个字符串的一个价值最大的非空后缀,并且要求这个后缀是一个回文串。输出这个最大的权值。
输入格式
输入文件的第一行是26个整数,依次给出a到z这26个字母的价值。
输入文件的第二行是一个字符串,长度不超过500000。
输出格式
输出一个整数,即满足条件的价值最大的字符串的价值。
输入样例
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 dacaeaca
输出样例
7
数据规模与约定
对20%的数据,字串长度不超过1000
对100%的数据,字串长度不超过500000
每组测试数据时限1秒
题目来源:天津市NOI选拔赛2009年第一轮
=============================================================================
模版题~不解释。
program suffix;
const
MaxN = 1000001;
var
str: array[1..MaxN] of char;
Rad: array[1..MaxN] of longint;
Sum: array[0..MaxN] of longint;
Sco: array['a'..'z'] of longint;
Len: longint;
procedure Scan;
var
ch: char;
begin
for ch := 'a' to 'z' do
Read(Sco[ch]);
readln;
Len := 0;
Sum[0] := 0;
while not EOF do
begin
Read(ch);
if (ch < 'a') or (ch > 'z') then
continue;
Inc(Len, 2);
Str[Len - 1] := '#';
Sum[Len - 1] := Sum[Len - 2];
Str[Len] := ch;
Sum[Len] := Sum[Len - 1] + Sco[ch];
end;
Inc(Len);
Str[Len] := '#';
Sum[Len] := Sum[Len - 1];
end;
function Min(a, b: longint): longint;
begin
if a < b then
exit(a)
else
exit(b);
end;
procedure Manacher;
var
Mx, Id, i: longint;
begin
Mx := 0;
for i := 1 to Len - 1 do
begin
if Mx > i then
Rad[i] := Min(Rad[(Id shl 1) - i], Mx - i)
else
Rad[i] := 1;
while Str[i - Rad[i]] = Str[i + Rad[i]] do
Inc(Rad[i]);
if Rad[i] + i > Mx then
begin
Mx := Rad[i] + i;
Id := i;
end;
end;
end;
function Ans: longint;
var
i: longint;
begin
Ans := -maxlongint;
for i := 1 to Len do
if (i + Rad[i] > Len) and (Sum[Len] - Sum[i - Rad[i]] > Ans) then
Ans := Sum[Len] - Sum[i - Rad[i]];
end;
procedure dubug;
var
i: longint;
begin
for i := 1 to Len do
Write(Str[i]: 5);
writeln;
for i := 1 to Len do
Write(Sum[i]: 5);
writeln;
for i := 1 to Len do
Write(Rad[i]: 5);
writeln;
end;
procedure Main;
begin
Scan;
Manacher;
Writeln(Ans);
//dubug;
end;
begin
Assign(input, 'suffix.in');
reset(input);
Assign(output, 'suffix.out');
rewrite(output);
Main;
Close(input);
Close(output);
end.