題目鏈接
http://acm.hdu.edu.cn/showproblem.php?pid=3613
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 940 Accepted Submission(s): 390
Input The first line of input is a single integer T (1 ≤ T ≤ 10) - the number of test cases. The description of these test cases follows.
Output Output a single Integer: the maximum value General Li can get from the necklace.
Sample Input 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 aba 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 acacac Sample Output 1 6 原串的前綴與(原串前後顛倒得到的反串)的前綴長度相同,那麼原串對應的這段字符則為回文串。模擬算出ex[i],可以得出ex[i]+i=len,且如果前半段(到i)不是回文,則直接判斷(i+1)以後的是否為回文即可。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <stack> using namespace std; const int inf=0x3fffffff; const int maxn=500000+10; char str1[maxn],str2[maxn]; int nt[maxn],ex1[maxn],ex2[maxn],dp[maxn]; int kind[26]; int slen,tlen; void get_next(char *s) { nt[0]=slen; int l,r; for(l=0;l<slen-1&&s[l]==s[l+1];l++); nt[1]=l; l=1; for(int i=2;i<slen;i++) { r=l+nt[l]-1; if(nt[i-l]+i-1>=r) { int p=r-i+1>0?r-i+1:0; while(p+i<slen&&s[p]==s[p+i]) p++; nt[i]=p; l=i; } else nt[i]=nt[i-l]; } } void get_extand(char *s,char *t,int *ex) { memset(nt,0,sizeof(nt)); get_next(s); int l=0,r; while(l<slen&&s[l]==t[l]) l++; ex[0]=l; l=0; for(int i=1;i<tlen;i++) { r=ex[l]+l-1; if(nt[i-l]+i-1>=r) { int p=r-i+1>0?r-i+1:0; while(p+i<tlen&&s[p]==t[i+p]) p++; ex[i]=p; l=i; } else ex[i]=nt[i-l]; } } int main() { //freopen("in.txt","r",stdin); int T; scanf("%d",&T); while(T--) { for(int i=0;i<26;i++) scanf("%d",&kind[i]); scanf("%s",str1); memset(dp,0,sizeof(dp)); dp[0]=0; tlen=slen=strlen(str1); for(int i=1;i<=slen;i++) dp[i]=dp[i-1]+kind[str1[i-1]-'a']; for(int i=slen-1,j=0;i>=0;i--,j++) str2[j]=str1[i]; str2[slen]='\0'; get_extand(str1,str2,ex1); get_extand(str2,str1,ex2); int ans=0; for(int i=0;i<slen;i++) { int temp=0; if(i&&ex1[i]+i==slen) { int p=ex1[i]; temp+=dp[p]; if(ex2[p]+p==slen) { temp+=dp[slen]-dp[p]; } } else { int p=i+1; if(ex2[p]+p==slen) temp+=dp[slen]-dp[p]; } ans=ans>temp?ans:temp; //printf("i->%d ans->%d\n",i,ans); } printf("%d\n",ans); } return 0; }