Manacher
https://www.cnblogs.com/fan1-happy/p/11166182.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| int f[N << 1]; char str[N << 1]; LL Manacher(char *s) { int n = strlen(s + 1); int maxLen = -1; str[1] = '#'; for(int i = 1; i <= n; i++) { str[i << 1] = s[i]; str[i << 1 | 1] = '#'; } n = n << 1 | 1; str[0] = '$'; str[n + 1] = '*'; int id = 1, mx = 1; LL ret = 0; for(int i = 1; i <= n; i++) { f[i] = min(f[id * 2 - i], mx - i); while(str[i - f[i]] == str[i + f[i]]) { f[i]++; } if(i + f[i] > mx) { mx = i + f[i]; id = i; } maxLen = max(maxLen, f[i] - 1); ret += f[i] >> 1; } cout << "maxLen = " << maxLen << endl; return ret; }
|
Ps:这个数组s
是从1开始计数的,因此aca
会变成$#a#c#a#
给出26个字母对应的价值。现要将一个字符串分成两截。一段字符串若是回文串则其价值为所有字母价值和,否则为0。问分割后的两串价值和最大是多少。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| #include <bits/stdc++.h> using namespace std; const int N = 500005; int value[30]; char s[N]; char str[N << 1]; int f[N << 1]; int pre[N]; int p[N];
void Manacher() { memset(f, 0, sizeof(f)); int n = strlen(s + 1); int len = strlen(s); int maxLen = str[1] = '#'; for(int i = 1; i <= n; i++) { str[i << 1] = s[i]; str[i << 1 | 1] = '#'; } n = n << 1 | 1; str[0] = '$'; str[n + 1] = '*'; int id = 1, mx = 1; for(int i = 1; i <= n; i++) { f[i] = min(f[id*2-i], mx-i); while(str[i - f[i]] == str[i + f[i]]) { f[i]++; } if(i + f[i] > mx) { id = i; mx = i + f[i]; } } memset(pre, 0, sizeof(pre)); for(int i = 1; i < len; i++) { pre[i] = pre[i - 1] + value[s[i] - 'a']; } int maxSum = 0; len -= 1; for(int i = 3; i < n; i += 2) { int sum = 0; if(f[(i+1) >> 1] * 2 - 1 == i) { sum += pre[(i - 1) >> 1]; } if(f[(i + n) >> 1] * 2 - 1 == n - i + 1) { sum += (pre[len] - pre[(i - 1) >> 1]); } maxSum = max(maxSum, sum); } printf("%d\n", maxSum); }
int main() { int n; scanf("%d", &n); while(n--) { for(int i = 0; i < 26; i++) { scanf("%d", &value[i]); } scanf("%s", &s); for(int i = strlen(s); i >= 0; i--) { s[i + 1] = s[i]; } Manacher(); } }
|