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);
    }
}

 

posted @ 2015-08-15 14:09  sweat123  阅读(258)  评论(0编辑  收藏  举报