caioj1462: 【EXKMP】回文串

不得不说这是一道好题(前排膜拜灯教授),其实这道题如果不说是EXKMP,很容易就想到Manacher(好像也可以这样做)

回到这道题,这样只有一个字符串,还要求回文?立刻想到了将这个串和它的反串跑EXKMP,举个例子:
假设字符串s[0]是acacac,那它的反串s[1]就是cacaca,互相跑EXKMP就有:
ex[0]={0,0,5,0,3,0,1}//这里的定义是以s[0]为模版串
ex[1]={0,0,5,0,3,0,1}
然后就可以枚举断的地方,假设a|cacac i=2
那定义一个j等于len-(i-1)+1就指向cacaca的最后一个a,等于6,然后得到ex[1][6]有多少个匹配的,当然了,6+ex[1][6]-1要等于len才行,不然这两个串就不是完全匹配的了。同理i后面的cacac也是这样搞,(当然你可以像灯教授和肉丝鸡掌一样搞个前缀和什么的省时间 %%%%%)

然而昨天灯教授故意卡了我,搞得我现在又要改成用前缀和了。。

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int a[30];
char s[2][510000];
int p[2][510000],ex[2][510000];
void exkmp(int len,int w)
{
    int x,k;
    p[1-w][1]=len;
    x=1;while(s[1-w][x]==s[1-w][x+1]&&x<=len)x++;
    p[1-w][2]=x-1;k=2;
    for(int i=3;i<=len;i++)
    {
        int P=k+p[1-w][k]-1,L=p[1-w][i-k+1];
        if(i-k+L<P-k+1)p[1-w][i]=L;
        else
        {
            int j=max(P-i+1,0);
            while(s[1-w][1+j]==s[1-w][i+j]&&i+j<=len)j++;
            p[1-w][i]=j;k=i;
        }
    }
    
    x=1;while(s[w][x]==s[1-w][x]&&x<=len)x++;
    ex[w][1]=x-1;k=1;
    for(int i=2;i<=len;i++)
    {
        int P=k+ex[w][k]-1,L=p[1-w][i-k+1];
        if(i-k+L<P-k+1)ex[w][i]=L;
        else
        {
            int j=max(P-i+1,0);
            while(s[1-w][1+j]==s[w][i+j]&&i+j<=len)j++;
            ex[w][i]=j;k=i;
        }
    }
}
int qz[2][510000];
void getsum(int len)
{
    int ans=0,ss,x,tp;
    for(int i=2;i<=len;i++)
    {
        ss=0;int j=len-(i-1)+1;
        if(j+ex[1][j]-1==len)ss+=qz[0][ex[1][j]];
        if(i+ex[0][i]-1==len)ss+=qz[1][ex[0][i]];
        if(ss>ans)ans=ss;
    }
    printf("%d\n",ans);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        for(int i=1;i<=26;i++)scanf("%d",&a[i]);
        scanf("%s",s[0]+1);int len=strlen(s[0]+1);
        for(int i=1;i<=len;i++)s[1][i]=s[0][len-i+1];
        qz[0][0]=0;qz[0][1]=0;
        for(int i=1;i<=len;i++)
        {
            qz[0][i]=qz[0][i-1]+a[s[0][i]-'a'+1];
            qz[1][i]=qz[1][i-1]+a[s[1][i]-'a'+1];
        }
        
        exkmp(len,0);exkmp(len,1);
        getsum(len);
    }
    return 0;
}

 

posted @ 2017-09-20 13:47  AKCqhzdy  阅读(263)  评论(0编辑  收藏  举报