【APIO2016】字符串匹配

来源:互联网 发布:get it beauty self 编辑:程序博客网 时间:2024/05/22 17:31

Description

这里写图片描述

Solution

刚看到这题,最有想法,这不是一道水题吗!
然后脑抽打了个后缀数组加KMP(其实只用KMP就好了),然后打的又臭又长,最后还爆零了。我的KMP尽然从1开始搜!!!!!TAT
主要思路:分两种情况
1、S比T短,设S在T中出现次数为o,然后答案先加上n*o,然后再找中间出现的次数,设S的长度为m,把T的后m-1个和T的前m-1个组成新的字符串A,然后求得S在A中的出现次数p,然后答案再加上p*(n-1)。
2、S比T长,先把T增添到比S长,假设增添了b次,那么有nb个串可以做上面的操作,然后还剩下一些字符串这些字符串肯定比S小,那么就把T的后m-1个串与剩下的串合并,再得出答案相加就好了。
看起来写的很长,其实很简单。

Code

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define fo(i,a,b) for(i=a;i<=b;i++)#define fod(i,a,b) for(i=a;i>=b;i--)using namespace std;const int maxn=300007;int i,j,k,l,t,m,len1,len2,p[maxn],da,len3;char s[maxn],st[maxn],sr[maxn],sq[maxn],ss[maxn];int sa[maxn],rank[maxn],height[maxn],zhi[maxn],fu[maxn],q[maxn],w,zuo,you,len4,len5;int js[maxn];long long ans,n,nn,bei;int main(){    scanf("%lld",&n);    scanf("%s",s+1);len1=strlen(s+1);    fo(i,2,len1){        while(k>0&&s[i]!=s[k+1])k=p[k];        if(s[i]==s[k+1])k++;        p[i]=k;    }    p[1]=0;    scanf("%s",st+1);len2=strlen(st+1);    if(len1<=len2){        k=0;l=0;        fo(i,1,len2){            while(k>0&&st[i]!=s[k+1])k=p[k];            if(st[i]==s[k+1])k++;            if(k==len1){                l++;                k=p[k];            }        }               ans=l*n;        fo(i,len2-len1+2,len2)sr[++len3]=st[i];        fo(i,1,len1-1)sr[++len3]=st[i];        k=0;w=0;l=0;        fo(i,1,len3){            while(k>0&&sr[i]!=s[k+1])k=p[k];            if(sr[i]==s[k+1])k++;            if(k==len1){                l++;                k=p[k];            }        }         ans=ans+l*(n-1);        printf("%lld\n",ans);    }    else{        while(len4<len1){            bei++;            fo(i,1,len2)sq[++len4]=st[i];        }            nn=n/bei;        k=0;l=0;        fo(i,1,len4){            while(k>0&&sq[i]!=s[k+1])k=p[k];            if(sq[i]==s[k+1])k++;            if(k==len1){                k=p[k];                l++;            }        }               ans=l*nn;        fo(i,len4-len1+2,len4)sr[++len3]=sq[i];        fo(i,1,len1-1)sr[++len3]=sq[i];        k=0;w=0;l=0;        fo(i,1,len3){            while(k>0&&sr[i]!=s[k+1])k=p[k];            if(sr[i]==s[k+1])k++;            if(k==len1){                k=p[k];                l++;            }        }         ans=ans+l*(nn-1);        fo(i,len4-len1+2,len4)ss[++len5]=sq[i];        fo(j,1,n-nn*bei)fo(i,1,len2)ss[++len5]=st[i];        k=0;l=0;        fo(i,1,len5){            while(k>0&&ss[i]!=s[k+1])k=p[k];            if(ss[i]==s[k+1])k++;            if(k==len1){                k=p[k];                l++;            }        }               ans+=l;        printf("%lld\n",ans);    }}
1 0
原创粉丝点击