AC日记——背单词 洛谷 P2353

背单词

 

思路:

  KMP+统计前缀和优化;

 

代码:

#include <bits/stdc++.h>
using namespace std;
#define maxn 1000005
int n,m,air[maxn][11],len_,len,bi[maxn],fail[maxn];
int lit[11],cnt,ans[maxn];
char ch[maxn],T[maxn];
inline void in(int &now)
{
    char Cget=getchar();now=0;
    while(Cget>'9'||Cget<'0')Cget=getchar();
    while(Cget>='0'&&Cget<='9')
    {
        now=now*10+Cget-'0';
        Cget=getchar();
    }
}
void KMP(int now)
{
    int k=-1,v=0;fail[v]=k;
    while(v<len_)
    {
        if(k==-1||T[v]==T[k]) k++,v++,fail[v]=k;
        else k=fail[k];
    }
    int i=0;v=0;
    while(i<=len)
    {
        if(v==-1||ch[i]==T[v]) v++,i++;
        else v=fail[v];
        if(v==len_)    air[i][now]++,v=fail[v];
    }
}
int main()
{
    in(n),in(m),scanf("%s",ch),len=strlen(ch);int l,r;
    for(int i=1;i<=n;i++) scanf("%s",T),len_=strlen(T),KMP(i),lit[i]=len_;
    for(int i=1;i<=len;i++)
    {
        for(int v=1;v<=n;v++) air[i][v]+=air[i-1][v];
    }
    for(int i=1;i<=m;i++)
    {
        in(l),in(r),cnt=0;
        for(int v=1;v<=n;v++)
        {
            if(l+lit[v]-1<=r)
            {
                cnt+=air[r][v]-air[l+lit[v]-2][v];
            }
        }
        printf("%d\n",cnt);
    }
    return 0;
}

 

posted @ 2017-06-18 11:23  IIIIIIIIIU  阅读(227)  评论(0编辑  收藏  举报