題意:
先給你每個字母的價值和一個字符串,讓你切一刀,這個字符串的總價值爲左子串的價值+右子串的價值,如果子串是迴文串,價值就是所有字符的價值之和,否則就是0。
思路:
先馬拉車預處理一下,然後從0到len-2遍歷,枚舉左邊和右邊的子串,要判斷左邊或者右邊是不是迴文串可以寫個函數,要知道在manacher如果迴文串中心在pos位置,左端點和右端點在原串的位置那個式子就行了,然後用個前綴和算出串的價值。
#include <bits/stdc++.h>
#define mt make_tuple
#define fi first
#define se second
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define forn(i, n) for (int i = 0; i < (int)(n); ++i)
#define for1(i, n) for (int i = 1; i <= (int)(n); ++i)
#define ford(i, a, b) for (int i = (int)(a); i >= (int)b; --i)
#define fore(i, a, b) for (int i = (int)(a); i <= (int)(b); ++i)
#define rep(i, l, r) for (int i = (l); i <= (r); i++)
#define per(i, r, l) for (int i = (r); i >= (l); i--)
#define ms(x, y) memset(x, y, sizeof(x))
using namespace std;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii> vpi;
typedef vector<vi> vvi;
typedef long long i64;
typedef vector<i64> vi64;
typedef vector<vi64> vvi64;
typedef pair<i64, i64> pi64;
typedef double ld;
template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }
const int maxn = 500001+100;
int tc, val[30], pref[maxn];
char ma[maxn << 1], s[maxn];
int mp[maxn << 1];
int manacher(char s[], int len) {
int l = 0, ans = 1;
ma[l++] = '$';
ma[l++] = '#';
for (int i = 0; i < len; ++i) {
ma[l++] = s[i];
ma[l++] = '#';
}
ma[l] = 0;
int mx = 0, id = 0;
for (int i = 0; i < l; ++i) {
mp[i] = mx > i ? min(mp[2 * id - i], mx - i) : 1;
while (ma[i - mp[i]] == ma[i + mp[i]]) ++mp[i];
if (i + mp[i] > mx) {
mx = i + mp[i];
id = i;
}
if (mp[i] - 1 > ans) ans = mp[i] - 1;
}
return ans;
}
int getL(int pos) {
return ((pos -(mp[pos] - 1) + 1) / 2 - 1);
}
int getR(int pos) {
return ((pos + (mp[pos] - 1) - 1) / 2 - 1);
}
int solve(int l, int r) {
int ml = (l+1)<<1, mr = (r+1)<<1;
int mid = (ml+mr)>>1;
if (getL(mid) == l && getR(mid) == r) return (pref[r+1]-pref[l]);
else return 0;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.precision(10);
cout << fixed;
#ifdef LOCAL_DEFINE
#endif
cin >> tc;
while (tc--) {
forn(i, 26) cin >> val[i];
cin >> s;
int len = strlen(s);
pref[0] = 0;
forn(i, len) {
pref[i+1] = pref[i]+val[int(s[i]-'a')];
}
manacher(s, len);
int ans = 0;
for (int i = 0; i < len-1; ++i) {
ans = max(ans, solve(0, i)+solve(i+1, len-1));
}
cout << ans << '\n';
}
#ifdef LOCAL_DEFINE
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}