标签:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MAXN = 1e6+7; const int MAXM = 1007; const int oo = 1e9+7; char str[MAXN]; int p[MAXN], val[27], sum[MAXN]; bool Left[MAXN], Right[MAXN]; /** str[] 先存原字符串,后存扩展后的字符串 p[] p[i] 表示以i为中心的回文串有多长(只记录一边的长度)、 sum[] sum[i]表示前i个字符的总价值和 Left[] Left[i] 表示前缀长度为 i 的串是否是回文串 Right[] Right[i] 表示后缀长度为 i 的串是否是回文串 **/ void Manacher(char str[], int N) { int i, id=0; for(i=2; i<N; i++) { if(p[id]+id > i) p[i] = min( p[id*2-i], p[id]+id-i); else p[i] = 1; while(str[ i+p[i] ] == str[ i-p[i] ]) p[i]++; if(p[id]+id < p[i]+i) id = i; if(p[i] == i) Left[p[i]-1] = true; if(p[i]+i-1 == N) Right[p[i]-1] = true; } } int main() { int T; scanf("%d", &T); while(T--) { int i; memset(Left, false, sizeof(Left)); memset(Right, false, sizeof(Right)); memset(p, false, sizeof(p)); for(i=0; i<26; i++) scanf("%d", &val[i]); scanf("%s", str); int len = strlen(str); for(i=1; i<=len; i++) sum[i] = sum[i-1]+val[str[i-1]-‘a‘]; for(i=len; i>=0; i--) { str[i+i+2] = str[i]; str[i+i+1] = ‘#‘; } str[0] = ‘$‘; Manacher(str, len+len+1); int ans = -oo; for(i=1; i<len; i++) { int temp = 0; if(Left[i] == true) temp += sum[i]; if(Right[len-i] == true) temp += sum[len]-sum[i]; ans = max(ans, temp); } printf("%d\n", ans); } return 0; }
Best Reward HDU 3613(回文子串Manacher)
标签:
原文地址:http://www.cnblogs.com/liuxin13/p/4747537.html