hdu-2222 Keywords Search (AC自动机板子题)

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#define RG register
#define IL inline
#define pi acos(-1.0)
#define ll long long 
using namespace std;

int gi() {
  char ch=getchar(); int x=0;
  while(ch<'0' || ch>'9') ch=getchar();
  while(ch>='0' && ch<='9') {x=10*x+ch-'0';ch=getchar();}
  return x;
}

const int maxn = 55;
const int maxm = 1000010;
const int size = 26;

int T,n,id,ans;
char s1[maxn],s2[maxm];
int ch[maxm][27];
int val[maxm],last[maxm],f[maxm];
bool bj[maxm];

queue<int> q;

void build(char *s) {
  int u=0,l=strlen(s);
  for(int i=0; i<l; i++) {
    int c=s[i]-'a';
    if(!ch[u][c]) ch[u][c]=id++;
    u=ch[u][c];
  }
  val[u]++;
}

void get_fail() {
  for(int c=0; c<size; c++) {
    int u=ch[0][c];
    if(u) q.push(u);//f[u]=0,last[u]=0;
  }
  while(!q.empty()) {
    int r=q.front(); q.pop();
    for(int c=0; c<size; c++) {
      int u=ch[r][c];
      if(!u) {ch[r][c]=ch[f[r]][c]; continue;}//Trie树变Trie图
      q.push(u);
      int v=f[r];
      while(v && !ch[v][c]) v=f[v];
      f[u]=ch[v][c];
      last[u]=val[f[u]]?f[u]:last[f[u]];
    }
  }
}

void find(char *s) {
  int j=0,l=strlen(s);
  for(int i=0; i<l; i++) {
    bj[j]=1;
    int c=s[i]-'a';
    j=ch[j][c];//j往下跳
    if(!bj[j]) {
      for(int z=j; z; z=last[z]) {
	ans+=val[z];
	val[z]=0;
      }
    }
  }
}

int main() {
  T=gi();
  while(T--) {
    id=1,ans=0;
    n=gi();
    for(int i=1; i<=n; i++) {
      scanf("%s", s1);
      build(s1);
    }
    get_fail();
    scanf("%s", s2);
    find(s2);
    printf("%d\n", ans);
    for(int i=0; i<id; i++) {
      f[i]=last[i]=val[i]=0;
      bj[i]=false;
      for(int c=0; c<size; c++) ch[i][c]=0;
    }
  }
  return 0;
}
/*
  多组数据记得清空数据
  不要重定义
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值