<kmp>codevs 1404 字符串匹配

来源:互联网 发布:摔跤知乎 编辑:程序博客网 时间:2024/05/17 14:17

题面传送门
以为是kmp的裸题(其实差不多233),结果调了半天,后来搜了题解才知道要怎么改。
在kmp算法的过程中,如果在每循环到i时,记ans[p]++。这个数组代表的意义是:到字符串A的第i个字符的最大匹配长度。但是,对于ans[nxt[p]],我们却没有作记录。所以在最后处理ans函数时,先倒序处理一遍(一定要倒序),这样才能累加。这样子处理出来的ans数组代表大于等于它的所有答案,最后的答案就是ans[x]-ans[x+1],所以再处理一遍ans数组就可以了。
注意:倒序循环时,不能循环到0,否则就会重复累加
代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=200000+10;char A[maxn],B[maxn];int n,m,k,x;int ans[maxn],nxt[maxn];void make_nxt(){    for(int i=1;i<m;++i)    {        int p=nxt[i];        while(p&&B[i+1]!=B[p+1]) p=nxt[p];        if(B[i+1]==B[p+1]) p++;        nxt[i+1]=p;    }}void kmp(){    int p=0;    for(int i=1;i<=n;++i)    {        while(p&&B[p+1]!=A[i])           p=nxt[p];        if(A[i]==B[p+1]) ++p;        ans[p]++;    }}int main(){    scanf("%d%d%d",&n,&m,&k);    scanf("%s\n%s",A+1,B+1);    make_nxt();    kmp();    for(int i=m;i>0;--i)       ans[nxt[i]]+=ans[i];    for(int i=0;i<=m;++i)       ans[i]-=ans[i+1];    for(int i=1;i<=k;++i)    {        scanf("%d",&x);        printf("%d\n",ans[x]);    }    return 0;} 
原创粉丝点击