EZOJ #78

传送门

分析

AC自动机板子题qwq

不过似乎可以哈希(因为所有模式串的长度相同,所以哈希乱搞就可以)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
int trie[1000005][27],fail[1000005],sum[1000005],cnt;
char s[1000010];
inline void build(){
      int n=strlen(s),p=0,i;
      for(i=0;i<n;i++){
          if(!trie[p][s[i]-'a'])trie[p][s[i]-'a']=++cnt;
          p=trie[p][s[i]-'a'];
      }
      sum[p]++;
}
queue<int>q;
inline void findfail(){
      int n,m,i,j,k;
      for(i=0;i<26;i++){
          if(trie[0][i]){
            fail[trie[0][i]]=0;
            q.push(trie[0][i]);
        }
      }
      while(!q.empty()){
          int x=q.front();q.pop();
          for(i=0;i<26;i++)
            if(trie[x][i]){
                fail[trie[x][i]]=trie[fail[x]][i];
                q.push(trie[x][i]);
            }else trie[x][i]=trie[fail[x]][i];
      }
}
inline void que(int m){
      int n=strlen(s),i,j,k,p=0,ans=0;
      for(i=0;i<n;i++){
          int ok=0;
          p=trie[p][s[i]-'a'];
          for(j=p;j,sum[j]!=-1;j=fail[j]){
            ans+=sum[j];
            if(sum[j])ok=1;
            sum[j]=-1;
            if(ok)break;
        }
        if(ok){
          printf("%d\n",i+2-m);
          exit(0);
        }
      }
      return;
}
int main(){
      int n,m,L,i,j,k;
      scanf("%d%d%d",&L,&n,&m);
      for(i=1;i<=n;i++){
          scanf("%s",s);
          build();
      }
      fail[0]=0;
      findfail();
      scanf("%s",s);
      que(m);
      puts("no");
      return 0;
}

猜你喜欢

转载自www.cnblogs.com/yzxverygood/p/9880214.html
78