hdu 6096 String

#include<stdio.h>
#include<string.h>
#include <algorithm>
#include<queue>
#include<string>
#include<iostream>
using namespace std;
const int maxn=(int)5e5+1e5;
const int maxm=(int)1e6+1e5+5;
#define meowmeow meow--

int pos[100005];

char s1[(int)2e5+10];
char s[maxm];
struct ac_shuaishuai
{
#define beg 'a'
#define sz 27
    int tot=0,f[maxn],nxt[maxn][sz],v[maxn],len[maxn];
    void init(int k=0){
        if(k==0)tot=0;
        memset(nxt[k],0,sizeof nxt[k]);
        f[k]=v[k]=len[k]=0;
    }
    int inst(const char s[]){
        int i=0,now=0;
        while(s[i]){
            int t=s[i]-beg;

            if(!nxt[now][t])
            {
                nxt[now][t]=++tot;
                init(tot);
            }
            now=nxt[now][t];
            len[now]=++i;
        }
        return now;
    }
    void bulid(){
        queue<int>q;
        q.push(0);
        while(!q.empty()){
            int x=q.front();
            q.pop();
            for(int i=0; i<sz; i++)
                if(nxt[x][i])
                {
                    if(nxt[x][i]!=nxt[f[x]][i])
                        f[nxt[x][i]]=nxt[f[x]][i];
                    q.push(nxt[x][i]);
                }
                else nxt[x][i]=nxt[f[x]][i];
        }
    }
    int match(const char s[]){
        int st=0;int wangwang;
        for(int i=0,j=1;s[i];i++,j++)
        {
            if(s[i]=='a'+27){j=0;continue;}
            if(s[i]=='a'+26) wangwang=j;
            st=nxt[st][s[i]-beg];
            for(int k=st; k; k=f[k])
                if(wangwang>=len[k]) v[k]++;
        }
        return 1;
    }
#undef beg
#undef sz
};
ac_shuaishuai ac;
int meow,n,m;
void init(){
    ac.init();
}
void input(){
    char c='a'+26;int beg=0,ed=0;
    for(int i=0;i<n;i++){
        scanf("%s",s+beg);
       // cout<<s<<endl;
        while(s[ed])ed++;s[ed++]=c;
        while(s[beg]!=c)s[ed++]=s[beg++];s[ed++]=c+1;
        beg=ed;s[beg]=0;
    }
    for(int i=1;i<=m;i++){
        int j=0,k=100005;
        scanf("%s %s",s1+k,s1);
        while(s1[j])j++;s1[j++]=c;
        while(s1[k])s1[j++]=s1[k++];s1[j]=0;
        pos[i]=ac.inst(s1);//记录该前后缀的结点号,这样就能处理重复查询同一个前后缀的问题了
    }
}
int main()
{

#ifdef shuaishuai
    freopen("C:\Users\hasee\Desktop\a.txt","r",stdin);
    //  freopen("C:\Users\hasee\Desktop\c.txt","w",stdout);
#endif

    scanf("%d",&meow);
    while(meowmeow)
    {
        scanf("%d%d
",&n,&m);
        init();
        input();
        ac.bulid();
        ac.match(s);
        for(int i=1;i<=m;i++){
            printf("%d
",ac.v[pos[i]]);
        }
    }

}
原文地址:https://www.cnblogs.com/MeowMeowMeow/p/7615634.html