暴力枚举大水题,判断回文,扩展KMP
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 500005; int a[30]; char str[500005]; char str1[500005]; int s[500005]; int _next[maxn],_extend[maxn]; int next1[maxn],extend1[maxn]; void getnext(char *T) { int a = 0; int Tlen = strlen(T); _next[0] = Tlen; while(a<Tlen-1&&T[a]==T[a+1]) a++; _next[1] = a; a = 1; for(int k=2; k < Tlen; k++) { int p = a + _next[a] - 1,L = _next[k-a]; if((k-1)+L>=p) { int j = (p-k+1) > 0 ? p - k + 1 : 0; while(k+j<Tlen&&T[k+j]==T[j]) j++; _next[k] = j; a = k; } else _next[k] = L; } } void getextend(char *S,char *T) { int a = 0; getnext(T); int Slen = strlen(S); int Tlen = strlen(T); int Minlen = Slen < Tlen ? Slen : Tlen; while(a<Minlen&&S[a]==T[a]) a++; _extend[0] = a; a = 0; for(int k = 1; k < Slen; k++) { int p = a + _extend[a] - 1,L = _next[k-a]; if((k-1)+L>=p) { int j = (p-k+1) > 0 ? p - k + 1 : 0; while(k+j<Slen&&j<Tlen&&S[k+j]==T[j]) j++; _extend[k] = j; a = k; } else _extend[k] = L; } } void getnext1(char *T) { int a = 0; int Tlen = strlen(T); next1[0] = Tlen; while(a<Tlen-1&&T[a]==T[a+1]) a++; next1[1] = a; a = 1; for(int k=2; k < Tlen; k++) { int p = a + next1[a] - 1,L = next1[k-a]; if((k-1)+L>=p) { int j = (p-k+1) > 0 ? p - k + 1 : 0; while(k+j<Tlen&&T[k+j]==T[j]) j++; next1[k] = j; a = k; } else next1[k] = L; } } void getextend1(char *S,char *T) { int a = 0; getnext1(T); int Slen = strlen(S); int Tlen = strlen(T); int Minlen = Slen < Tlen ? Slen : Tlen; while(a<Minlen&&S[a]==T[a]) a++; extend1[0] = a; a = 0; for(int k = 1; k < Slen; k++) { int p = a + extend1[a] - 1,L = next1[k-a]; if((k-1)+L>=p) { int j = (p-k+1) > 0 ? p - k + 1 : 0; while(k+j<Slen&&j<Tlen&&S[k+j]==T[j]) j++; extend1[k] = j; a = k; } else extend1[k] = L; } } int main() { int T; scanf("%d",&T); while(T--) { for(int i = 0; i < 26; i++) scanf("%d",&a[i]); scanf("%s",str); int len = strlen(str); s[0] = a[ str[0] - 'a' ]; for(int i = 1; i < len; i++) s[i] = s[i-1] + a[ str[i]-'a' ]; for(int i = 0; i < len; i++) str1[i] = str[len-i-1]; getextend(str1,str); getextend1(str,str1); int ans = 0; for(int i = 0; i < len-1; i++) { if(_extend[len-i-1]==i+1&&extend1[i+1]==len-i-1) ans = max(ans,s[len-1]); else if(_extend[len-i-1]==i+1) ans = max(ans,s[i]); else if(extend1[i+1]==len-i-1) ans = max(ans,s[len-1]-s[i]); } printf("%d ",ans); } return 0; }