Pagini recente » Cod sursa (job #1683886) | Cod sursa (job #677543) | Cod sursa (job #783492) | Cod sursa (job #2056031) | Cod sursa (job #2704064)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define pb push_back
#define dbg(x) cerr << #x << " " << x << "\n"
const int MAX_N = 2e5, MAX_K = 20;
int pos[MAX_N];
char str[MAX_N], s[MAX_K];
int order[MAX_N];
inline bool cmp (int a, int b) {
return pos[a] < pos[b];
}
struct Faster {
int a;
int b;
int idx;
bool operator < (const Faster &other) const {
if (a == other.a)
return b < other.b;
return a < other.a;
}
};
Faster tags[MAX_N];
vector <Faster> freq[1 + MAX_N];
void radix_sort (int n) {
int mx_tag = 0;
for (int i = 0; i < n; i++) {
mx_tag = max (mx_tag, tags[i].a);
mx_tag = max (mx_tag, tags[i].b);
}
for (int i = 0; i <= mx_tag; i++)
freq[i].clear ();
for (int i = 0; i < n; i++)
freq[tags[i].b].pb (tags[i]);
int nr = 0;
for (int i = 0; i <= mx_tag; i++)
for (Faster f : freq[i])
tags[nr++] = f;
for (int i = 0; i <= mx_tag; i++)
freq[i].clear ();
for (int i = 0; i < n; i++)
freq[tags[i].a].pb (tags[i]);
nr = 0;
for (int i = 0; i <= mx_tag; i++)
for (Faster f : freq[i])
tags[nr++] = f;
}
inline void get_order () {
int n = strlen (str);
for (int i = 0; i < n; i++)
if (str[i] >= 'a' && str[i] <= 'z')
pos[i] = 1 + str[i] - 'a' + 26;
else
pos[i] = 1 + str[i] - 'A';
for (int depth = 0; (1 << depth) <= n; depth++) {
int length = (1 << depth);
for (int i = 0; i < n; i++) {
int a = pos[i], b;
if (i + length < n)
b = pos[i + length];
else
b = 0;
tags[i] = {a, b, i};
}
//sort (tags, tags + n);
radix_sort (n);
pos[tags[0].idx] = 1;
for (int i = 1; i < n; i++)
if (tags[i].a == tags[i - 1].a && tags[i].b == tags[i - 1].b)
pos[tags[i].idx] = pos[tags[i - 1].idx];
else
pos[tags[i].idx] = 1 + pos[tags[i - 1].idx];
}
for (int i = 0; i < n; i++)
order[i] = i;
sort (order, order + n, cmp);
}
int k;
inline int compare (int start) {
for (int i = 0; i < k; i++)
if (str[i + start] != s[i])
return (str[i + start] < s[i]) ? -1 : 1;
return 0;
}
char part[64];
int main () {
freopen ("seti.in", "r", stdin);
freopen ("seti.out", "w", stdout);
ios::sync_with_stdio (false);
cin.tie (0); cout.tie (0);
int n;
cin >> n;
int nr = 0;
for (int i = 0; i < n; i++) {
cin >> part;
for (int j = 0; j < 64; j++)
str[nr++] = part[j];
}
n *= 64;
get_order ();
int m;
cin >> m;
while (m--) {
cin >> s;
k = strlen (s);
int lb = 0, rb = n - 1;
int start = n;
while (lb <= rb) {
int mid = (lb + rb) / 2;
if (compare (order[mid]) < 0)
lb = mid + 1;
else
rb = mid - 1, start = mid;
}
lb = start, rb = n - 1;
int finish = 0;
while (lb <= rb) {
int mid = (lb + rb) / 2;
if (compare (order[mid]) > 0)
rb = mid - 1;
else
lb = mid + 1, finish = mid;
}
cout << max (0, finish - start + 1) << "\n";
}
return 0;
}