#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
#define pb push_back
#define ff first
#define ss second
const int base = 73;
struct TR{
struct node{
int nt[5], f;
};
vector<node> t;
vector<char> C;
int cc, S;
void init(){
t.pb(node());
t.pb(node());
C = {'J', 'A', 'C', 'G', 'U'};
cc = 1;
S = 0;
}
int f(char x){
if (x == 'A') return 1;
if (x == 'C') return 2;
if (x == 'G') return 3;
return 4;
}
void add(string s){
int v = 1;
for (char x: s){
int y = f(x);
if (!t[v].nt[y]){
t[v].nt[y] = ++cc;
t.pb(node());
}
v = t[v].nt[y];
}
t[v].f++;
S += (int) s.size();
}
vector<int> tin, tout;
vector<pair<ull, int>> all;
int timer;
string s;
void dfs(int v){
tin[v] = ++timer;
if (t[v].f){
ull h = 0, b = 1;
for (int i = (int) s.size() - 1; i >= 0; i--){
h += b * f(s[i]);
b *= base;
for (int j = 0; j < t[v].f; j++){
all.pb({h, tin[v]});
}
}
}
for (int i = 1; i < 5; i++){
int y = t[v].nt[i];
if (!y) continue;
s += C[i];
dfs(y);
s.pop_back();
}
tout[v] = timer;
}
vector<vector<int>> mp;
vector<ull> ii;
void build(){
s = "";
timer = 0;
tin.resize(S + 1);
tout.resize(S + 1);
dfs(1);
sort(all.begin(), all.end());
int i = 0;
while (i < all.size()){
mp.pb({});
ii.pb(all[i].ff);
int j = i;
while (j < all.size() && all[i].ff == all[j].ff){
mp.back().pb(all[j].ss);
j++;
}
i = j;
}
}
vector<ull> :: iterator it;
vector<int> :: iterator it1, it2;
int get(string p, string q){
int v = 1;
for (char x: p){
int y = t[v].nt[f(x)];
if (!y) return 0;
v = y;
}
int l = tin[v], r = tout[v];
ull h = 0, b = 1;
for (int i = (int) q.size() - 1; i >= 0; i--){
h += b * f(q[i]);
b *= base;
}
it = lower_bound(ii.begin(), ii.end(), h);
int j = (int) (it - ii.begin());
it1 = lower_bound(mp[j].begin(), mp[j].end(), l);
it2 = upper_bound(mp[j].begin(), mp[j].end(), r);
return (int) (it2 - it1);
}
};
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n, q; cin>>n>>q;
TR T; T.init();
while (n--){
string s; cin>>s;
T.add(s);
}
T.build();
while (q--){
string p, q; cin>>p>>q;
cout<<T.get(p, q)<<"\n";
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |