首页 > 代码库 > HDU 3613 Best Reward(扩展KMP)

HDU 3613 Best Reward(扩展KMP)

 

【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=3613

 

【题目大意】 

  一个字符串的价值定义为,当它是一个回文串的时候,价值为每个字符的价值的和,如果不是回文串,价值为0,现在给出每种字符的价值。给出一个字符串,要求将其划分为两个子串,要求两个子串的价值和最大。

 

【题解】 

  求出字符串S的反串T,以T为模板跑一遍S的exkmp就能得到S的后缀是否为回文串的信息,同理以S为模板跑一遍T就可以得到S的前缀是否是回文串的信息,枚举每个断点,取最大值即可。

 

【代码】 

#include <cstdio>#include <cstring> using namespace std;const int N=500010;int len,LCP[N],ex1[N],ex2[N],a[N],s[N];char S[N],T[N];void getLCP(char *T){    int i,len=strlen(T);    LCP[0]=len;    for(i=0;i<len-1&&T[i]==T[i+1];i++);    LCP[1]=i; int a=1;    for(int k=2;k<len;k++){        int p=a+LCP[a]-1,L=LCP[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++;            LCP[k]=j,a=k;        }else LCP[k]=L;    } }void exkmp(char *S,char *T,int *extend){    memset(LCP,0,sizeof(LCP));     getLCP(T);     int Slen=strlen(S),Tlen=strlen(T),a=0;    int MinLen=Slen>Tlen?Tlen:Slen;    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=LCP[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 revcpy(char* S,char* T,int len){     memset(T,0,sizeof(T));     for(int i=0,k=len-1;i<len;++i,--k)T[i]=S[k]; }int Cas;int main(){    scanf("%d",&Cas);    while(Cas--){        for(int i=0;i<26;i++)scanf("%d",&a[i]);        scanf("%s",S);len=strlen(S);        for(int i=0;S[i];i++)s[i+1]=s[i]+a[S[i]-‘a‘];        revcpy(S,T,len);        exkmp(S,T,ex2);         exkmp(T,S,ex1);        int ans=-1e9;        for(int i=0;i<len;i++){            if(i&&ex1[i]+i==len){                int j=ex1[i],tmp=s[j];                if(ex2[j]+j==len)tmp+=s[len]-s[j];                if(tmp>ans)ans=tmp;            }else{                int j=i+1,tmp=0;                if(ex2[j]+j==len)tmp+=s[len]-s[j];                if(tmp>ans)ans=tmp;            }        }printf("%d\n",ans);    }return 0;}

 

HDU 3613 Best Reward(扩展KMP)