HDU 4300 Clairewd’s message(扩展KMP)

这题的意思就是首先有一个字母的转换表,就是输入的第一行的字符串,就是'a'转成第一个字母,'b'转成转换表的第二个字母·······
然后下面一个字符串是密文+明文的形式的字符串。
就是说前后两段是重复的,只不过通过转换表转换了下。
而且后面一段可能不完整。
这道题问的就是将1个串如何变为stringA+stringB的形式,使得stringA是stringB经过映射得到相同的串。映射那步其实没有什么价值,假设str为原串s经过映射后得到的串,我们可以以str为模式串,以s为原串做一次扩展KMP,得到extend数组,extend[i]表示原串以第i开始与模式串的前缀的最长匹配。经过O(n)的枚举,我们可以得到,若extend[i]+i=len且i>=extend[i]时,表示stringB即为该点之前的串,stringA即为该点之前的str串,最后输出即可。
#include<bits/stdc++.h>
using namespace std;
const int M=2e5+5;
char sa[M],sb[M],mima[M];
int lena,lenb;
int p[M],ex[M];
map<char,char>mp;
//p数组是用来让B串自己匹配自己的 
void exkmp()
{
    p[1]=lenb;
    int x=1;
    while(sb[x]==sb[x+1]&&x+1<=lenb) x++;//因为我们p[1]是具有一定性,所以我们不能直接用,所以要先暴力求出p[2] 
    p[2]=x-1;
    int k=2;
    for(int i=3;i<=lenb;i++)
    {
        int pp=k+p[k]-1,L=p[i-k+1];//pp实际上是p 
        if(i+L<pp+1) p[i]=L;//i-k+L<pp-k+1化简后i+L<pp 
        else
        {
            int j=pp-i+1;
            if(j<0) j=0;
            while(sb[j+1]==sb[i+j]&&i+j<=lenb) j++;
            p[i]=j;
            k=i;
        }
    }
    x=1;
    while(sa[x]==sb[x]&&x<=lenb) x++;//ex[1]并不具有一定性,所以我们暴力求出ex[1] 
    ex[1]=x-1;
    k=1;
    for(int i=2;i<=lena;i++)
    {
        int pp=k+ex[k]-1,L=p[i-k+1];
        if(i+L<pp+1) ex[i]=L;
        else
        {
            int j=pp-i+1;
            if(j<0) j=0;
            while(sb[j+1]==sa[i+j]&&i+j<=lena&&j<=lenb) j++;
            ex[i]=j;
            k=i;
        }
    }
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%s%s",mima+1,sa+1);
        lena=strlen(sa+1);
        lenb=lena;

        for(int i=1;i<=strlen(mima+1);i++)
            mp[mima[i]]='a'+i-1;
        for(int i=1;i<=lena;i++)
            sb[i]=mp[sa[i]];
        sb[lena+1]=0;
        exkmp();

        int i;
        for(i=1;i<=lena;i++)
            if(i-1+ex[i]>=lena&&i-1>=ex[i])
                break;
        for(int j=1;j<i;j++)
            printf("%c",sa[j]);
        for(int j=1;j<i;j++)
            printf("%c",mp[sa[j]]);
        puts("");
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/starve/p/11689343.html