题意:
给你一串字符串,每个字符都有一个权值,要求把这个字符串在某点分开,使之成为两个单独的字符串
如果这两个子串某一个是回文串,则权值为那一个串所有的字符权值和
若不是回文串,则权值为0
解析:
先用Manacher算法求出以每个字母为中心的回文串的长度,并计算该字符串的前缀价值和。然后枚举切割点,得到两份子串。这样就可以知道每个子串的中心点,然后检查以该子串的中心点作为中心点的回文串的长度,如果长度等于该子串的长度,那么就加上该子串的价值。然后和最优价值比较就行了。
注意只有一个字符时输出0
#include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> #include <cmath> #define rap(i, a, n) for(int i=a; i<=n; i++) #define rep(i, a, n) for(int i=a; i<n; i++) #define lap(i, a, n) for(int i=n; i>=a; i--) #define lep(i, a, n) for(int i=n; i>a; i--) #define rd(a) scanf("%d", &a) #define rlld(a) scanf("%lld", &a) #define rc(a) scanf("%c", &a) #define rs(a) scanf("%s", a) #define MOD 2018 #define LL long long #define ULL unsigned long long #define Pair pair<int, int> #define mem(a, b) memset(a, b, sizeof(a)) #define _ ios_base::sync_with_stdio(0),cin.tie(0) //freopen("1.txt", "r", stdin); using namespace std; const int maxn = 500010, INF = 0x7fffffff; char s[maxn], s_new[maxn<<1]; int p[maxn<<1], a[30], sum[maxn]; int init(char *s) { int len = strlen(s); s_new[0] = '$'; s_new[1] = '#'; int j = 2; rep(i, 0, len) { s_new[j++] = s[i]; s_new[j++] = '#'; } s_new[j++] = '\0'; // cout<< strlen(s_new) <<endl; return j; } void manacher(char *s) { int len = init(s); // int max_len = -1; int id, mx = 0; rep(i, 1, len) { if(i < mx) p[i] = min(p[2*id-i], mx - i); else p[i] = 1; while(s_new[i-p[i]] == s_new[i+p[i]]) p[i]++; if(mx < i+p[i]) { id = i; mx = i+p[i]; } } } int T; int main() { rd(T); while(T--) { rep(i, 0, 26) rd(a[i]); rs(s); if(strlen(s) == 1) { cout<< "0" <<endl; continue; } sum[0] = a[s[0] - 'a']; int len = strlen(s); rep(i, 1, len){ sum[i] = sum[i-1] + a[s[i] - 'a']; // cout<< sum[i] <<endl; } manacher(s); int len2 = strlen(s_new); int res = -INF; for(int i=3; i<len2 - 2; i+=2) { int ans = 0; if(p[i/2+1] - 1 == i/2) ans += sum[i/2-1]; if(p[i+(len2-i)/2] - 1 == (len2-i)/2) ans += sum[len-1] - sum[i/2-1]; res = max(res, ans); } cout<< res <<endl;
} return 0; }