Pagini recente » Cod sursa (job #1553632) | Cod sursa (job #255518) | Cod sursa (job #1507964) | Cod sursa (job #1131366) | Cod sursa (job #1184397)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
int n;
string s;
vector<int> sa;
vector<int> rank;
vector<int> lcp;
vector<int> llcp;
vector<int> rlcp;
bool cmp(int x, int y)
{
return s[x] < s[y];
}
void buildsa()
{
sa.resize(n);
rank.resize(n);
for (int i = 0; i < n; i++) {
sa[i] = i;
}
sort(sa.begin(), sa.end(), cmp);
vector<int> oldsa(n);
vector<int> oldrank(n);
vector<int> pos(n+1);
for (int len = 1; ; len *= 2) {
int cnt = 0;
swap(rank, oldrank);
for (int i = 0; i < n; i++) {
int x = sa[i];
bool eq;
if (i == 0) {
eq = false;
}
else {
int w = sa[i-1];
if (len == 1) {
eq = s[w] == s[x];
}
else {
// assume that s[n-1] is different from s[i] for i in 0..n-2
eq = oldrank[w] == oldrank[x] && oldrank[w+len/2] == oldrank[x+len/2];
}
}
if (eq) {
pos[cnt]++;
}
else {
pos[++cnt] = 1;
}
rank[x] = cnt-1;
}
if (cnt == n) {
break;
}
pos[0] = 0;
for (int i = 1; i <= cnt; i++) {
pos[i] += pos[i-1];
}
swap(sa, oldsa);
for (int i = n-len; i < n; i++) {
sa[pos[rank[i]]++] = i;
}
for (int i = 0; i < n; i++) {
int x = oldsa[i]-len;
if (x >= 0) {
sa[pos[rank[x]]++] = x;
}
}
}
}
void buildlcp()
{
lcp.resize(n);
// assume that sa[0] = n-1
for (int i = 0, len = 0; i < n-1; i++) {
int h = sa[rank[i]-1];
// assume that s[n-1] is different from s[i] for i in 0..n-2
while (s[h+len] == s[i+len]) {
len++;
}
lcp[rank[i]] = len;
if (len > 0) {
len--;
}
}
}
void buildllcp()
{
llcp.assign(lcp.begin(), lcp.end());
for (int stp = 2; stp < n; stp *= 2) {
for (int i = stp; i < n; i += stp) {
llcp[i] = min(llcp[i], llcp[i-stp/2]);
}
}
}
void buildrlcp()
{
rlcp.assign(lcp.begin()+1, lcp.end());
rlcp.push_back(0);
for (int stp = 2; stp < n; stp *= 2) {
for (int i = 0; i < n; i += stp) {
rlcp[i] = i+stp >= n ? 0 : min(rlcp[i], rlcp[i+stp/2]);
}
}
}
int count(const string & t)
{
int stp = 1;
while (stp*2 < n) {
stp *= 2;
}
// assume that length of lcp of t and s[sa[0]] is 0
int lo = 0;
for (int w = 0, y = 0; stp; stp /= 2) {
int mi = lo+stp;
if (mi >= n) {
y = 0;
continue;
}
int x;
bool b;
if (w < y) {
x = min(y, rlcp[mi]);
b = y == rlcp[mi];
}
else {
x = min(w, llcp[mi]);
b = w == llcp[mi];
}
if (b) {
int m = t.size();
while (x < m && s[sa[mi]+x] == t[x]) {
x++;
}
if (x == m) {
int lo = mi, up = mi;
do {
if (rlcp[lo-stp] >= m) {
lo -= stp;
}
if (up+stp < n && llcp[up+stp] >= m) {
up += stp;
}
stp /= 2;
} while (stp);
return up+1-lo;
}
}
if (s[sa[mi]+x] < t[x]) {
lo = mi;
w = x;
}
else {
y = x;
}
}
return 0;
}
int main()
{
freopen("ahocorasick.in", "r", stdin);
freopen("ahocorasick.out", "w", stdout);
ios::sync_with_stdio(false);
cin >> s;
s += '\0';
n = s.size();
buildsa();
buildlcp();
buildllcp();
buildrlcp();
int m;
cin >> m;
for (int i = 0; i < m; i++) {
string t;
cin >> t;
printf("%d\n", count(t));
}
return 0;
}