#include <bits/stdc++.h>
#define all(v) begin(v), end(v)
using namespace std;
const int MAXN = 1e5 + 5;
int numStr, numQuery, res[MAXN];
string S[MAXN], P[MAXN], Q[MAXN];
struct TrieTwo{
struct Node{
int child[26], cnt;
Node(){
memset(child, -1, sizeof child);
cnt = 0;
}
};
int sizeTrie;
vector<int> pos;
vector<Node> node;
int newNode(){
node.push_back(Node());
return sizeTrie++;
}
TrieTwo(){
sizeTrie = 0;
newNode();
}
void addString(const string &s, const int &id){
pos.push_back(id);
int cur = 0;
for(int i = 0; i < (int)s.size(); i++){
int c = s[i] - 'A';
if (node[cur].child[c] == -1) node[cur].child[c] = newNode();
cur = node[cur].child[c];
node[cur].cnt++;
}
}
int getQuery(const string &s){
int cur = 0;
for(int i = 0; i < (int)s.size(); i++){
int c = s[i] - 'A';
if (node[cur].child[c] == -1) return 0;
cur = node[cur].child[c];
}
return node[cur].cnt;
}
};
struct TrieOne{
struct Node{
int child[26];
vector<int> pos, query;
Node(){
memset(child, -1, sizeof child);
}
};
int sizeTrie;
vector<Node> node;
int newNode(){
node.push_back(Node());
return sizeTrie++;
}
TrieOne(){
sizeTrie = 0;
newNode();
}
void addString(const string &s, int id, bool type = 0){
int cur = 0;
for(int i = 0; i < (int)s.size(); i++){
int c = (int)s[i] - 'A';
if (!type && node[cur].child[c] == -1) node[cur].child[c] = newNode();
else if (type && node[cur].child[c] == -1) return;
cur = node[cur].child[c];
}
if (!type) node[cur].pos.push_back(id);
else node[cur].query.push_back(id);
}
TrieTwo dfs(int u){
TrieTwo canU;
for(int id: node[u].pos) canU.addString(S[id], id);
for(int c = 0; c < 26; c++){
int v = node[u].child[c];
if (v == -1) continue;
TrieTwo canV = dfs(v);
if (canU.sizeTrie < canV.sizeTrie) swap(canU, canV);
for(int id: canV.pos) canU.addString(S[id], id);
}
for(int id: node[u].query) res[id] += canU.getQuery(P[id]);
return canU;
}
};
TrieOne myTrie;
void input(){
cin >> numStr >> numQuery;
for(int i = 1; i <= numStr; i++) cin >> S[i];
for(int i = 1; i <= numQuery; i++) cin >> P[i] >> Q[i];
}
void solve(){
for(int i = 1; i <= numStr; i++){
reverse(all(S[i]));
myTrie.addString(S[i], i);
reverse(all(S[i]));
}
for(int i = 1; i <= numQuery; i++){
reverse(all(Q[i]));
myTrie.addString(Q[i], i, 1);
reverse(all(Q[i]));
}
myTrie.dfs(0);
for(int q = 1; q <= numQuery; q++) cout << res[q] << '\n';
}
int main(){
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
if (fopen("test.inp", "r")){
freopen("test.int", "r", stdin);
freopen("test.out", "w", stdout);
}
input();
solve();
}
Compilation message (stderr)
selling_rna.cpp: In function 'int main()':
selling_rna.cpp:128:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
128 | freopen("test.int", "r", stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
selling_rna.cpp:129:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
129 | freopen("test.out", "w", stdout);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~| # | 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... |