Cod sursa(job #3297621)

Utilizator SleepyOverlordPatcas Csaba SleepyOverlord Data 23 mai 2025 03:31:02
Problema Aho-Corasick Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.09 kb
//Code by Patcas Csaba aka SleepyOverlord
#include <vector>
#include <array>
#include <string> 
#include <set> 
#include <map> 
#include <unordered_set>
#include <unordered_map>
#include <queue> 
#include <bitset> 
#include <stack>
#include <list>

#include <numeric> 
#include <algorithm> 
#include <random>
#include <chrono>

#include <cstdio>
#include <fstream>
#include <iostream> 
#include <sstream> 
#include <iomanip>
#include <climits>

#include <cctype>
#include <cmath> 
#include <ctime>
#include <cassert>

using namespace std;

#define ULL unsigned long long
#define LL long long
#define PII pair <int, int>
#define PLL pair <LL, LL>
#define VB vector <bool>
#define VI vector <int>
#define VLL vector <LL>
#define VD vector <double>
#define VS vector <string>
#define VPII vector <pair <int, int> >
#define VVI vector < VI >
#define VVLL vector < VLL >
#define VVB vector < VB >
#define SI set < int >
#define USI unordered_set <int>
#define MII map <int, int>
#define UMII unordered_map <int, int>

#define FORN(i, n) for(int i = 0; i < (n); ++i)
#define FOR(i, a, b) for(int i = (a); i <= (b); ++i)
#define FORD(i, a, b) for(int i = (a); i >= (b); --i)
#define MX(x, y) x = max(x, y)
#define MN(x, y) x = min(x, y)

#define SZ size()
#define BG begin() 
#define EN end() 
#define CL clear()
#define X first
#define Y second
#define RS resize
#define PB push_back
#define MP make_pair
#define ALL(x) x.begin(), x.end()
#define ALL1(x) x.begin() + 1, x.end()
#define INS insert
#define ER erase
#define CNT count

template <class T> ostream& operator <<(ostream & os, const vector<T> &vec)
{
	for (int i = 0; i < vec.size() - 1; ++i) os << vec[i] << ' ';
	return os << vec[vec.size() - 1];
}

template <class T1, class T2> ostream& operator <<(ostream & os, const pair<T1, T2> &p)
{
	return os << p.X << " " << p.Y;
}

template <typename T>
void pr(T var1)
{
	cout << var1 << '\n';
}
template <typename T, typename... Types>
void pr(T var1, Types... var2)
{
	cout << var1;
	pr(var2...);
}

int n;
string text, pattern;
VVI dp;
VI sa;
vector <pair <PII, int> > a, b;

int comp(int suffix)
{
	if (suffix == -1) return -1;
	else
		if (suffix == n) return 1;
	suffix = sa[suffix];
	FOR(i, suffix, suffix + pattern.SZ - 1)
	{
		if (i >= n) return -1;
		else
			if (text[i] < pattern[i - suffix]) return -1;
			else
				if (text[i] > pattern[i - suffix]) return 1;
	}
	return 0;
}

int bs(bool lower)
{
	int left = -1, right = n;
	while (right - left > 1)
	{
		int mid = (left + right) / 2;
		if (lower)
		{
			if (comp(mid) < 0) left = mid;
			else right = mid;
		}
		else
		{
			if (comp(mid) <= 0) left = mid;
			else right = mid;
		}
	}
	return right;
}

void radix(int classes)
{
	VI cnt(classes + 1);
	FORN(i, n) ++cnt[a[i].X.Y];
	FOR(i, 1, classes) cnt[i] += cnt[i - 1];
	FORD(i, n - 1, 0) b[--cnt[a[i].X.Y]] = a[i];
	fill(ALL(cnt), 0);
	FORN(i, n) ++cnt[b[i].X.X];
	FOR(i, 1, classes) cnt[i] += cnt[i - 1];
	FORD(i, n - 1, 0) a[--cnt[b[i].X.X]] = b[i];
}

int main()
{
	#ifdef AT_HOME
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);
	#else
	freopen("ahocorasick.in", "r", stdin);
	freopen("ahocorasick.out", "w", stdout);
	#endif

	ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);

	int start = clock();

	cin >> text;
	n = text.SZ;
	int lg = 1;
	while ((1 << lg) < n) ++lg;
	lg = min(lg, 16);

	cerr << clock() - start << endl;

	dp.RS(2, VI(n));
	a.RS(n), b.RS(n);
	FOR(j, 0, n - 1) dp[0][j] = text[j] - 'a' + 1;
	int row = 1, c = 26;
	FOR(i, 1, lg)
	{
		int p2 = 1 << (i - 1);
		FORN(j, n) a[j] = {{dp[row ^ 1][j], (j + p2 < n) ? dp[row ^ 1][j + p2] : 0}, j};
		radix(c);
		c = 1;
		FORN(j, n)
		{
			if (j > 0 and a[j].X != a[j - 1].X) ++c;
			dp[row][a[j].Y] = c;
		}
		if (c == n) break;
		row ^= 1;
	}
	sa.RS(n);
	FORN(i, n) sa[dp[row][i] - 1] = i;

	cerr << clock() - start << endl;

	int q;
	cin >> q;
	FORN(qq, q)
	{
		cin >> pattern;
		int l = bs(true), r = bs(false);
		pr(r - l);
	}

	cerr << clock() - start << endl;

	return 0;
}