ベスト報酬[HDU - 3613](manacherアルゴリズム)
苦しい戦いの後、一般的な李は偉大な勝利を獲得しました。今、国家元首は、彼の偉大な悪用のための名誉と宝物をもって彼に報酬を与えることにしました。
これらの宝物の一つは、宝石の26の異なる種類の構成されたネックレスで、ネックレスの長さはNです。(つまり、言うことである:nは宝石は、このネックレスを構成するために一緒に弦楽器、及びこれらの宝石の各々は、唯一の26種に属しています。)
古典ビューに従い、ネックレスは貴重な場合であり、それは回文である場合にのみ - ネックレスはどちらの方向にも同じに見えます。しかし、我々は前述のネックレスは、冒頭に回文ない場合があります。だから、国家元首は、2つの部分にネックレスをカットし、[全般リーにそれらの両方を与えることにしました。
同じ種類のすべての宝石は(あるため、その品質の正または負でもよい - いくつか他の人が普通の石のようなルックスを得る一方、いくつかの種類が美しいです)と同じ値を持っています。回文であるネックレスは、その宝石値との和に等しい値を有します。回文ではないのネックレスは、値ゼロを有しています。
さて問題は、2つのネックレスの値の合計が最大になるように、与えられたネックレスをカットする方法。出力はこの値。
入力
テストケースの数 - 入力の最初の行は、単一の整数T(1≤T≤10)です。これらのテスト・ケースの説明は次のとおり。
各テストケースのために、最初の行は26個の整数である:V 1、V 2、...、V 26(-100≤VI≤100、1≤I≤26)、各種類の宝石の値を表します。
各テストケースの2行目は「」「Z」のキャラクターから構成される文字列です。ネックレスを表します。異なる宝石の種類を表すキャラクター、及び 'の値はV 1であり、bの値は、V 2、...、などです。文字列の長さは、これ以上500000以下ではありません。
出力
出力単一の整数:一般的なLiはネックレスから得ることができる最大値。
サンプル入力
2
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
aba
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
acacac
サンプル出力
1
6
質問の意味:
与えられた文字列s、および文字「」から「Z」値は、
あなたは、連続ストリング部2の任意の文字列に分割することができ、各部分の値です。
文字列のこの部分は回文文字列の場合、それ以外の値は0で、値が文字の値であり、合計が含まれています。
最大値はどのくらい後にお聞き分割されますか?
アイデア:
[I]はI〜(1-インデックスを使用して文字列)の和を文字列の値を表し、1:接頭辞配列と
manacherアルゴリズム処理文字列sと、彼の最も長いパリンドローム半径配列を取得\(\ mathit P \)
我々が知っている\(P [I] -1 \ ) 代表\(\ mathit I \)パリンドロームの最長の長さの中心とを。
私たちは、文字列のプレフィックス長は、除列挙(I、I \ [に\ \ 1、lenの-1])
次に、文字列sの長さ\(\ mathit I \)プレフィックス\(S [1 \ドットI ] \)はパリンドローム配列である:\(P [I + 1] - = 1 I \)。
次に、文字列sの長さ\(\ mathit I \)接尾辞\(S [lenの- I + 1 \ドットLEN] \) パリンドローム配列である:\(P [I + LEN + 1] - = 1。 LEN - I \)
最大の価値を維持するために。
コード:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#include <sstream>
#include <bitset>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
#define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
#define du2(a,b) scanf("%d %d",&(a),&(b))
#define du1(a) scanf("%d",&(a));
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) { if (a == 0ll) {return 0ll;} a %= MOD; ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
ll poww(ll a, ll b) { if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a ;} a = a * a ; b >>= 1;} return ans;}
void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
inline long long readll() {long long tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
inline int readint() {int tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
const int maxn = 500010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int val[maxn];
char s[maxn];
int len;
char s_new[maxn * 2 + 10];
int p[maxn * 2 + 10];
int Len;
int sum[maxn];
void init()
{
Len = len * 2 + 2;
int index = 0;
s_new[index++] = '$';
repd(i, 1, len)
{
s_new[index++] = '#';
s_new[index++] = s[i];
}
s_new[index++] = '#';
s_new[index++] = '\0';
// chu(s_new);
}
void manacher()
{
int R = 0;
int mid = 0;
repd(i, 1, Len)
{
p[i] = i < R ? min(R - i, p[2 * mid - i]) : 1;
while (s_new[i - p[i]] == s_new[i + p[i]])
{
p[i]++;
}
if (i + p[i] > R)
{
R = i + p[i];
mid = i;
}
}
}
int main()
{
//freopen("D:\\code\\text\\input.txt","r",stdin);
//freopen("D:\\code\\text\\output.txt","w",stdout);
int t;
t = readint();
while (t--)
{
repd(i, 'a', 'z')
{
val[i] = readint();
}
scanf("%s", s + 1);
len = strlen(s + 1);
repd(i, 1, len)
{
sum[i] = sum[i - 1] + val[s[i]];
}
init();
manacher();
int ans = -inf;
repd(i, 1, len - 1)
{
int temp = 0;
if (p[i + 1] - 1 == i)
{
temp += sum[i];
}
if (p[i + 1 + len] - 1 == len - i)
{
temp += sum[len] - sum[i];
}
ans = max(ans, temp);
}
printf("%d\n", ans );
}
return 0;
}