HDU 2896 AC自动机 裸题

中文题题意不再赘述

注意字符范围是可见字符,从32开始到95

char c - 32

 

#include <stdio.h>

#include <string.h>

#include <queue>

#include <algorithm>

using namespace std;

inline int Max(int a,int b){return a>b?a:b;}

inline int Min(int a,int b){return a>b?b:a;}



#define N 10000

#define maxnode 57000

#define sigma_size 95

int pre[3];

struct Trie{

	int ch[maxnode][sigma_size];

	int val[maxnode];

	int f[maxnode];

	int sz;

	void init(){

		sz=1;

		memset(ch[0],0,sizeof(ch[0]));

		val[0] = 0;

	}

	int idx(char c){

		return c-32;

	}



	void Creat(char *s, int num){  

		int u = 0, len = strlen(s);  

		for(int i = 0; i < len; i++){  

			int c = idx(s[i]);  

			if(!ch[u][c]){ memset(ch[sz],0,sizeof(ch[sz])); val[sz]=0; ch[u][c] = sz++;  }

			u = ch[u][c];        

		}  

		val[u]  = num ; //u若是单词结尾则为 +1

	}  



	int find(char *T, int num){

		int len = strlen(T);

		int j = 0;

		int fir = 0;

		f[0] = 0;

		for(int i = 0; i < len; i++){

			int c = idx(T[i]);



			j = ch[j][c];

			if(!j) j = ch[0][c];

			int temp = j;

			while(temp && val[temp]){



				if(!fir) printf("web %d:", num);

				

				pre[fir++] = val[j];

				if(fir == 3)break;



				temp = f[temp];

			}

		}



		if(fir){

			sort(pre, pre+fir);

			for(int k = 0; k < fir; k++)printf(" %d",pre[k]);

			printf("\n");

		}

		return fir>0;

	}



	void getFail(){

		queue<int> q;

		f[0] = 0;

		//初始化队列

		for(int c = 0; c < sigma_size; c++)

			if(ch[0][c])q.push(ch[0][c]);



		while(!q.empty()){

			int r = q.front(); q.pop();

			for(int c = 0; c < sigma_size; c++){

				int u = ch[r][c];

				if(!u){ ch[r][c] = ch[f[r]][c]; continue; }

				q.push(u);

				int v = f[r];

				while(v && !ch[v][c]) v = f[v]; //沿失配边追溯到可以匹配的(非原点)位置

				f[u] = ch[v][c];

			}

		}

	}

};

Trie ac;

char S1[N],S2[N];



void InputString(){	

	gets(S1);



}

int main(){



	int n;



	while(~scanf("%d",&n)){

		ac.init();

		getchar();

		for(int i = 1; i <= n; i++){

			InputString();

			ac.Creat(S1, i);

		}

		ac.getFail();



		int ANS = 0;

		scanf("%d",&n);

		getchar();

		for(int i = 1; i <= n; i++){

		InputString();

		ANS += ac.find(S1, i);

		}

		printf("total: %d\n",ANS);

	}

	return 0;

}

/*  

3  

a aa  

bbb  

ccc  

2  

a aabbbccc  

bbaacc  

  

ans:  

web 1: 1 2 3

total: 1

  

*/  


 

 

你可能感兴趣的:(AC自动机)