BNUOJ 34990 Justice String (基于hash的LCP)

来源:互联网 发布:淘宝被公司屏蔽怎么办 编辑:程序博客网 时间:2024/06/16 21:57

转自http://blog.csdn.net/w20810/article/details/48438047

题意:给定字符串A和B,在A里面找一个子串s,在s里面最多修改2个字符后使得s和B相同。求s的起始位置。

还是那种套路,不过这个地方的f1,f2,f3表示得挺好的。。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef unsigned long long ULL;const int maxn = 2e5+6;const int seed = 131;ULL H[maxn],X[maxn];char s1[maxn],s2[maxn];int Len1,Len2,L;void Init(){    H[L]=0;    for(int i=L-1;i>=0;i--)        H[i]=H[i+1]*seed+s1[i]-'a';    X[0]=1;    for(int i=1;i<L;i++)        X[i]=X[i-1]*seed;}inline ULL GetHash(int i,int L) //{    return H[i]-H[i+L]*X[L];}int LCP(int a,int b){    int ret=0,down=1,up=L-b,mid;    while(down<=up)    {        mid=(down+up)>>1;        if(GetHash(a,mid)==GetHash(b,mid))        {            down=mid+1;            if(mid>ret)                 ret=mid;        }        else            up=mid-1;    }    return ret;}int main(){    int ncase,i,j,f1,f2,f3,ans;    scanf("%d",&ncase);    for(int T=1;T<=ncase;T++)    {        scanf("%s%s",s1,s2);        Len1=strlen(s1);        Len2=strlen(s2);        L=Len1+Len2;        strcat(s1,s2);        Init();        for(i=0;i<=Len1-Len2;i++)        {            f1=LCP(i,Len1);            if(f1==Len2)                break;            f1++;            f2=LCP(i+f1,Len1+f1);            if(f1+f2==Len2)                break;            f2++;            f3=LCP(i+f1+f2,Len1+f1+f2);            if(f1+f2+f3==Len2)                break;        }        printf("Case #%d: %d\n",T,((i<=Len1-Len2)?i:-1));    }    return 0;}