hdu3613 扩展KMP
#include<stdio.h> #include<string.h> #define maxn 501000 char s[maxn],t[maxn]; int next[maxn],extand1[maxn],extand2[maxn]; int ans[30],sum[maxn]; void getnext(int *next,char *t) { int i,k,j,len=strlen(t); next[0]=len; i=0; while(i<len-1&&t[i]==t[i+1]) { i++; } next[1]=i; int a=1; for(k=2;k<len;k++) { int p=next[a]+a-1; int l=next[k-a]; if(k-1+l>=p) { int j=p-k+1>0?p-k+1:0; while(k+j<len&&t[k+j]==t[j]) j++; next[k]=j; a=k; } else next[k]=l; } } void ekmp(char *s,char *t,int *next,int *extand) { int i,j,slen=strlen(s),tlen=strlen(t),k; getnext(next,t);//求next数组 /* for(i=0;i<tlen;i++) printf("%d ",next[i]); printf("\n"); */ int minlen=slen<tlen?slen:tlen; int a=0; while(a<minlen&&s[a]==t[a]) a++; extand[0]=a; a=0; for(k=1;k<slen;k++) { int p=a+extand[a]-1; int 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++; extand[k]=j; a=k; } else extand[k]=l; } /*for(i=0;i<slen;i++) printf("%d ",extand[i]); printf("\n");*/ } int main() { int i,j,te; scanf("%d",&te); while(te--) { for(i=0;i<26;i++) scanf("%d",&ans[i]); scanf("%s",s); int len=strlen(s); for(i=0;i<len;i++) { t[len-i-1]=s[i]; if(i==0) sum[i]=ans[s[i]-'a']; else sum[i]=sum[i-1]+ans[s[i]-'a']; } t[len]='\0'; ekmp(s,t,next,extand1);//s做主串 ekmp(t,s,next,extand2);//t做主串 /*for(i=0;i<len;i++) { printf("%d ",extand1[i]); } printf("\n"); for(i=0;i<len;i++) { printf("%d ",extand2[i]); } printf("\n");*/ int max=-99999999; int ret; for(i=1;i<len;i++) { ret=0; if(extand1[i]+i==len) { ret+=sum[len-1]-sum[i-1]; } if(extand2[len-i]==i)//len-i表示t中的位置 { ret+=sum[i-1]; } if(ret>max) max=ret; } printf("%d\n",max); } }