Cod sursa(job #1982279)

Utilizator RazvanR104Razvan-Andrei Ciocoiu RazvanR104 Data 18 mai 2017 00:39:33
Problema Aho-Corasick Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.1 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 7e5 + 10;

int N;
char text[NMAX];
map<char, int> suffixEdge[2 * NMAX];
int suffixLink[2 * NMAX], suffixLength[2 * NMAX];
int DP[2 * NMAX];
bitset<2 * NMAX> vis;

void DFS(int node) {
	vis[node] = 1;
	for (auto nextNode: suffixEdge[node]) {
		if (!vis[nextNode.second])
			DFS(nextNode.second);
		DP[node] += DP[nextNode.second];
	}
}

int main() {
	assert(freopen("ahocorasick.in", "r", stdin));
	assert(freopen("ahocorasick.out", "w", stdout));
	int i;
	cin >> text;
	int currNode = 0, lastNode = 0, cntNode = 1;
	suffixLink[0] = -1;
	suffixLength[0] = 0;
	for (i = 0; text[i]; ++i) {
		currNode = cntNode++;
		suffixEdge[lastNode][text[i]] = currNode;
		suffixLength[currNode] = suffixLength[lastNode] + 1;
		int currSuffix = suffixLink[lastNode];
		while (currSuffix != -1 && !suffixEdge[currSuffix].count(text[i])) {
			suffixEdge[currSuffix][text[i]] = currNode;
			currSuffix = suffixLink[currSuffix];
		}
		if (currSuffix != -1) {
			int nextSuffix = suffixEdge[currSuffix][text[i]];
			if (suffixLength[nextSuffix] == suffixLength[currSuffix] + 1) {
				suffixLink[currNode] = nextSuffix;
			} else {
				int newNode = cntNode++;
				suffixLength[newNode] = suffixLength[currSuffix] + 1;
				suffixEdge[newNode] = suffixEdge[nextSuffix];
				suffixLink[newNode] = suffixLink[nextSuffix];
				suffixLink[nextSuffix] = suffixLink[currNode] = newNode;
				while (currSuffix != -1 && suffixEdge[currSuffix][text[i]] == nextSuffix) {
					suffixEdge[currSuffix][text[i]] = newNode;
					currSuffix = suffixLink[currSuffix];
				}
			}
		} else
			suffixLink[currNode] = 0;
		lastNode = currNode;
	}
	currNode = lastNode;
	while (currNode != -1) {
		DP[currNode] = 1;
		currNode = suffixLink[currNode];
	}
	DFS(0);
	cin >> N;
	while (N--) {
		cin >> text;
		currNode = 0;
		for (i = 0; text[i]; ++i) {
			if (!suffixEdge[currNode].count(text[i])) {
				cout << "0\n";
				goto Continue;
			}
			currNode = suffixEdge[currNode][text[i]];
		}
		cout << DP[currNode] << '\n';
		Continue:;
	}
	return 0;
}