【JZOJ 4624】字符串匹配

Description

这里写图片描述
串长度小于10^5,1<=n<=10^12

Analysis

KMP匹配。
要加上连接处的贡献
对于S串长于T串的情况要特殊处理,把T串长度弄成>=S串,再乱搞。
注意细节。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int N=100010;
ll n,m;
int next[N];
char a[N],b[N],c[N],d[N];
void get(char *s)
{
    int len=strlen(s+1),j=0;
    fo(i,2,len)
    {
        while(j && s[i]!=s[j+1]) j=next[j];
        next[i]=s[i]==s[j+1]?(++j):(j=0);
    }
}
int kmp(char *s1,char *s2)
{
    get(s2);
    int j=0,ans=0,len1=strlen(s1+1),len2=strlen(s2+1);
    fo(i,1,len1)
    {
        while(j && s1[i]!=s2[j+1]) j=next[j];
        if(s1[i]==s2[j+1]) j++;
        if(j==len2) ans++;
    }
    return ans;
}
int main()
{
    ll k,x,y,ans=0;
    scanf("%lld\n%s\n%s",&k,a+1,b+1);
    n=strlen(a+1),m=strlen(b+1);
    if(n>m)
    {
        int m1=m,t=n/m;
        if(n%m!=0) t++;
        if(k<t)
        {
            printf("0");
            return 0;
        }
        m=m*t;
        fo(i,m1+1,m) b[i]=b[(i-1)%m1+1];
        if(k%t)
        {
            fo(i,1,(k%t)*m1) c[i]=b[(i-1)%m+1];
            ans+=kmp(c,a);
            fo(i,1,n-1) d[i]=b[m-(n-1)+i];
            fo(i,1,min(n-1,(k%t)*m1)) d[n-1+i]=c[i];
            ans+=kmp(d,a);
        }
        k/=t;
    }
    x=kmp(b,a);
    fo(i,1,n-1) c[i]=b[m-n+i+1];
    fo(i,n,n+n-2) c[i]=b[i-n+1];
    y=kmp(c+1,a+1);
    printf("%lld",ans+k*x+(k-1)*y);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值