Cod sursa(job #3226266)

Utilizator dorufDoru Floare doruf Data 20 aprilie 2024 19:27:03
Problema Aho-Corasick Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2 kb
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
//#define int ll
using vi = vector<int>;
using pii = pair<int,int>;
using vpii = vector<pii>;
using vll = vector<ll>;
using vvi = vector<vector<int>>;
#define eb emplace_back

const int N = 1e6 + 5;
const int SIGMA = 26;

int n;
string a, s;

namespace AhoCorasick {
	int trie[N][SIGMA];
	int kmp[N];
	int curr = 1;
	vi adj[N];
	int occ[N];
	int cnt[N];
	
	inline int f(const char ch) {
		return ch - 'a';
	}
	
	void insert(const string& s, int idx) {
		int node = 0;
		for (int i = 0; i < s.size(); ++i) {
			if (!trie[node][f(s[i])]) 
				trie[node][f(s[i])] = curr++;
			node = trie[node][f(s[i])];
		}
		adj[node].eb(idx);
	}
	
	void build() {
		queue<int> q;
		for (int i = 0; i < SIGMA; ++i)
			if (trie[0][i])
				q.emplace(trie[0][i]);
				
		while (!q.empty()) {
			int u = q.front();
			q.pop();
			
			for (int i = 0; i < SIGMA; ++i) {
				if (!trie[u][i]) continue;
				
				int v = kmp[u];
				while (v && trie[v][i] == 0)
					v = kmp[v];
				
				if (trie[v][i]) {
					kmp[trie[u][i]] = trie[v][i];
					for (auto it : adj[trie[v][i]])
						adj[trie[u][i]].eb(it);
				}
				
				q.emplace(trie[u][i]);
			}
		}
	}
	
	void solve() {
		int node = 0;
		for (int i = 0; i < a.size(); ++i) {
			while (node && trie[node][f(a[i])] == 0)
				node = kmp[node];
			node = trie[node][f(a[i])];
			++cnt[node];
		}
		
		for (int u = 0; u < curr; ++u) {
			if (!cnt[u]) continue;
			for (auto v : adj[u])
				occ[v] += cnt[u];
		}
	}
};

int32_t main() {
	#ifdef ONLINE_JUDGE
    freopen("ahocorasick.in", "r", stdin);
		freopen("ahocorasick.out", "w", stdout);
	#endif
	
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

 	cin >> a >> n;
 	for (int i = 1; i <= n; ++i) {
 		cin >> s;
 		AhoCorasick::insert(s, i);
 	}
 	AhoCorasick::build();
 	AhoCorasick::solve();
	
	for (int i = 1; i <= n; ++i)
		cout << AhoCorasick::occ[i] << '\n';
}