codevs1404字符串匹配

/*
无奈我改了那么久还是看的题解
首先跑一边kmp 几下ans[p]表示总共匹配到长度p的次数
这些不一定都是恰好到p 所以在处理一下 
ans[p]通过处理变成 所有的匹配到长度p的次数
最后答案就是总共匹配到长度p+1的次数 - 总共匹配到长度p的次数
就是恰好匹配到长度p的次数 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 200010
using namespace std;
int l1,l2,k,s,fail[maxn],ans[maxn];
char s1[maxn],s2[maxn];
void kmp_init()
{
    for(int i=2;i<=l2;i++)
      {
          int p=fail[i-1];
          while(p&&s2[p+1]!=s2[i])
            p=fail[p];
          if(s2[p+1]==s2[i])
            fail[i]=p+1;
          else p=0;
      }
    return ;
}
void kmp_slove()
{
    int p=0;
    for(int i=1;i<=l1;i++)
      {
          while(p&&s2[p+1]!=s1[i])
            p=fail[p];
          if(s2[p+1]==s1[i])p++;
        ans[p]++;
      }
}
int main()
{
    scanf("%d%d%d",&l1,&l2,&k);
    scanf("%s%s",s1+1,s2+1);
    kmp_init();
    kmp_slove();
    for(int i=l2;i>0;i--) 
      ans[fail[i]]+=ans[i];
    for(int i=0;i<l2;i++)
      ans[i]-=ans[i+1];
    for(int i=1;i<=k;i++)
      {
          scanf("%d",&s);
          printf("%d\n",ans[s]);
      }
    return 0;
}

 

posted @ 2016-05-09 18:09  一入OI深似海  阅读(278)  评论(0编辑  收藏  举报