题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3613
题解:
代码一(下标从0开始):
#include<bits/stdc++.h> #define rep(i,a,n) for(int (i) = a; (i)<=(n); (i)++) #define ms(a,b) memset((a),(b),sizeof((a))) using namespace std; typedef long long LL; const double EPS = 1e-6; const int INF = 2e9; const LL LNF = 9e18; const int MOD = 1e9+7; const int MAXN = 5e5+10; void pre_EXKMP(char x[], int m, int Next[]) { Next[0] = m; int j = 0; while(j+1<m && x[0+j]==x[1+j]) j++; Next[1] = j; int k = 1; for(int i = 2; i<m; i++) { int p = Next[k]+k-1; int L = Next[i-k]; if(i+L<=p) Next[i] = L; else { j = max(0, p-i+1); while(i+j<m && x[i+j]==x[0+j]) j++; Next[i] = j; k = i; } } } void EXKMP(char x[], int m, char y[], int n, int Next[], int exd[]) { pre_EXKMP(x,m,Next); int j = 0; while(j<n && j<m && x[j]==y[j]) j++; exd[0] = j; int k = 0; for(int i = 1; i<n; i++) { int p = exd[k]+k-1; int L = Next[i-k]; if(i+L<=p) exd[i] = L; else { j = max(0,p-i+1); while(i+j<n && j<m && y[i+j]==x[0+j]) j++; exd[i] = j; k = i; } } } char s1[MAXN], s2[MAXN]; int val[30], Next[MAXN], exd1[MAXN], exd2[MAXN], sum[MAXN]; int main() { int T; scanf("%d",&T); while(T--) { rep(i,0,25) scanf("%d",&val[i]); scanf("%s",s1); int len = strlen(s1); rep(i,1,len) { sum[i] = sum[i-1] + val[s1[i-1]-'a']; s2[len-i] = s1[i-1]; } EXKMP(s1, len, s2, len, Next, exd1); EXKMP(s2, len, s1, len, Next, exd2); int ans = 0; for(int i = 1; i<len; i++) { int tmp = 0; if(exd1[len-i]==i) tmp += sum[i]; if(exd2[i]==len-i) tmp += sum[len]-sum[i]; ans = max(ans,tmp); } printf("%d\n", ans); } }
代码二(下标从1开始):
#include<bits/stdc++.h> #define rep(i,a,n) for(int (i) = a; (i)<=(n); (i)++) #define ms(a,b) memset((a),(b),sizeof((a))) using namespace std; typedef long long LL; const double EPS = 1e-6; const int INF = 2e9; const LL LNF = 9e18; const int MOD = 1e9+7; const int MAXN = 5e5+10; void pre_EXKMP(char x[], int m, int Next[]) { Next[1] = m; int j = 0; while(2+j<=m && x[1+j]==x[2+j]) j++; Next[2] = j; int k = 2; for(int i = 3; i<=m; i++) { int p = Next[k]+k-1; int L = Next[i-k+1]; if(i+L<=p) Next[i] = L; else { j = max(0, p-i+1); while(i+j<=m && x[i+j]==x[1+j]) j++; Next[i] = j; k = i; } } } void EXKMP(char x[], int m, char y[], int n, int Next[], int exd[]) { pre_EXKMP(x,m,Next); int j = 1; while(j<=n && j<=m && x[j]==y[j]) j++; exd[1] = j-1; int k = 1; for(int i = 2; i<=n; i++) { int p = exd[k]+k-1; int L = Next[i-k+1]; if(i+L<=p) exd[i] = L; else { j = max(0, p-i+1); while(i+j<=n && j<=m && y[i+j]==x[1+j]) j++; exd[i] = j; k = i; } } } char s1[MAXN], s2[MAXN]; int val[30], Next[MAXN], exd1[MAXN], exd2[MAXN], sum[MAXN]; int main() { int T; scanf("%d",&T); while(T--) { for(int i = 0; i<26; i++) scanf("%d",&val[i]); scanf("%s",s1+1); int len = strlen(s1+1); for(int i = 1; i<=len; i++) { sum[i] = sum[i-1] + val[s1[i]-'a']; s2[len-i+1] = s1[i]; } EXKMP(s1, len, s2, len, Next, exd1); EXKMP(s2, len, s1, len, Next, exd2); int ans = 0; for(int i = 1; i<=len-1; i++) { int tmp = 0; if(exd1[len-i+1]==i) tmp += sum[i]; if(exd2[i+1]==len-i) tmp += sum[len]-sum[i]; ans = max(ans,tmp); } printf("%d\n", ans); } }