病毒侵袭持续中 HDU - 3065

刚开始树里的数组开小了...TLE    询问字符串长度不够 RE了   未考虑多组输入,WA,,

AC

#include 
#include 
#include 
#include 
#include 

using namespace std;

const int N = 50*1000+5;
const int maxlen=2e6+100;

char buf[1000+5][50+5];
int ans[1000+5];

struct Trie {
	int next[N][128], fail[N], end[N];
	int cnt;
	int root, L;

	int newnode() {
		for(int i = 0; i < 128; i++)
			next[L][i] = -1;
		end[L++] = -1;
		return L-1;
	}

	void init() {
		L = cnt = 0;
		root = newnode();
	}
	void insert(char s[],int id) {
		int len = strlen(s);
		int now = root;
		for(int i = 0; i < len; i++) {
			if(next[now][s[i]] == -1)
				next[now][s[i]] = newnode();
			now=next[now][s[i]];
		}
		end[now]=id;
	}
	void build() {
		queueQ;
		fail[root] = root;
		for(int i = 0; i < 128; i++)
			if(next[root][i] == -1)
				next[root][i] = root;
			else {
				fail[next[root][i]] = root;
				Q.push(next[root][i]);
			}
		while(!Q.empty()) {
			int now = Q.front();
			Q.pop();

			for(int i = 0; i < 128; i++)
				if(next[now][i] == -1)
					next[now][i] = next[fail[now]][i];
				else {
					fail[next[now][i]] = next[fail[now]][i];

					Q.push(next[now][i]);
				}
		}
	}

	void query(char tmp[]) {
		int len = strlen(tmp);
		int now = root;

		bool flag = false;

		for(int i = 0; i < len; i++) {
			now = next[now][tmp[i]];
			int temp = now;

			while(temp != root) {
				if(end[temp] != -1) {
					ans[end[temp]]++;
				}
				temp = fail[temp];
			}
		}
	}
};
Trie ac;
int main() {
	int n,m;
	while(~scanf("%d",&n)){
		ac.init();
		memset(ans, 0, sizeof(ans));
		for(int i = 1; i <= n; i++) {
			scanf("%s",buf[i]);
			ac.insert(buf[i], i);
		}
		ac.build();

		char TMP[maxlen];

		scanf("%s", TMP);
		ac.query(TMP);

		for(int i=1; i<=n; i++)
			if(ans[i])
				printf("%s: %d\n",buf[i], ans[i]);
	}


	return 0;
}

 

 

//TLE了............. 

#include 
#include 
#include 
#include 
#include 

using namespace std;

const int N = 1000+5;

char buf[N][50+5];
int ans[N];
int n,m;

struct Trie {
	int next[50*1000+5][128],fail[50*1000+5],end[50*1000+5];
	int used[1010];
	int cnt;
	int root, L;

	int newnode() {
		for(int i = 0; i < 128; i++)
			next[L][i] = -1;
		end[L++] = -1;
		return L-1;
	}

	void init() {
		L = cnt = 0;
		root = newnode();
	}
	void insert(char s[],int id) {
		int len = strlen(s);
		int now = root;
		for(int i = 0; i < len; i++) {
			if(next[now][s[i]] == -1)
				next[now][s[i]] = newnode();
			now=next[now][s[i]];
		}
		end[now]=id;
	}
	void build() {
		queueQ;
		fail[root] = root;
		for(int i = 0; i < 128; i++)
			if(next[root][i] == -1)
				next[root][i] = root;
			else {
				fail[next[root][i]] = root;
				Q.push(next[root][i]);
			}
		while(!Q.empty()) {
			int now = Q.front();
			Q.pop();

			for(int i = 0; i < 128; i++)
				if(next[now][i] == -1)
					next[now][i] = next[fail[now]][i];
				else {
					fail[next[now][i]] = next[fail[now]][i];

					Q.push(next[now][i]);
				}
		}
	}

	void query(char tmp[],int n) {
		int len = strlen(tmp);
		int now = root;

		memset(used,false,sizeof(used));

		bool flag = false;

		for(int i = 0; i < len; i++) {
			now = next[now][tmp[i]];
			int temp = now;

			while(temp != root) {
				if(end[temp] != -1) {
					if(ans[end[temp]] == 0)
						used[cnt++] = end[temp];
		
					ans[end[temp]]++;

					flag = true;
				}
				temp = fail[temp];
			}
		}
//		cout << cnt << endl;
		//	cout << n << endl;
		//if(!flag)return false;
		for(int i = 1; i <= n; i++)
		if(ans[i])
			printf("%s: %d\n", buf[i], ans[i]);

		//	return true;
	}
};
Trie ac;
int main() {
	while(~scanf("%d",&n))
	{
		ac.init();
		memset(ans, 0, sizeof(ans));

		for(int i = 1; i <= n; i++) {
			scanf("%s",buf[i]);
			ac.insert(buf[i], i);
		}
		ac.build();
		int ans = 0;
		char TMP[2*1000000+5];

		scanf("%s", TMP);
		ac.query(TMP, n);
	}
	return 0;
}

 

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