#include <bits/stdc++.h>
using namespace std;
#define task "test"
#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 sz(a) (int)(a).size()
#define all(a) (a).begin(), (a).end()
#define bit(s, i) (((s) >> (i)) & 1)
#define ii pair <int, int>
#define vii vector <ii>
#define vi vector <int>
#define fi first
#define se second
#define ll long long
#define eb emplace_back
#define pb push_back
#define __builtin_popcount __builtin_popcountll
void solve();
int32_t main() {
if(fopen(task".inp", "r")) {
freopen(task".inp", "r", stdin);
freopen(task".out", "w", stdout);
}
cin.tie(0)->sync_with_stdio(0);
int tc = 1; // cin >> tc;
FOR(i, 1, tc) {
solve();
}
}
const int N = 1e5+5;
int n, m, trch[200], queryAns[N];
pair <string, int> s[N];
vector <ii> query[N*20];
struct fenwickTree {
int f[N*20];
void upd(int id, int val) {
for(; id<N*20; id+=id&-id) f[id]+=val;
}
int get(int id) {
int res=0;
for(; id>0; id-=id&-id) res+=f[id];
return res;
}
int getRange(int L, int R) {
return get(R) - get(L-1);
}
} fwt;
// build prefix trie
int Time, st[N*20], en[N*20];
struct preNode {
int cnt = 0, child[4];
preNode () {
fill(begin(child), end(child), -1);
}
};
vector <preNode> preTrie(1);
int pre_add_string(const string &newString) {
int cur = 0;
for(char c:newString) {
int nxtCh = trch[(int)c];
if(preTrie[cur].child[nxtCh] == -1) {
preTrie[cur].child[nxtCh] = sz(preTrie);
preTrie.eb();
}
cur = preTrie[cur].child[nxtCh];
}
preTrie[cur].cnt++;
return cur;
}
void pre_trie_dfs(int u) {
st[u] = ++Time;
FOR(i, 0, 3) {
if(preTrie[u].child[i] != -1) {
pre_trie_dfs(preTrie[u].child[i]);
}
}
en[u] = Time;
}
int pre_get_string(const string &f) {
int cur = 0;
for(char c:f) {
int nxtCh = trch[(int)c];
if(preTrie[cur].child[nxtCh] == -1) {
preTrie[cur].child[nxtCh] = sz(preTrie);
preTrie.eb();
}
cur = preTrie[cur].child[nxtCh];
}
return cur;
}
// build suffix trie
int sub[N*20], suf_st[N*20], suf_en[N*20], tour[N*20];
struct sufNode {
int cnt = 0, id = -1, child[4];
sufNode () {
fill(begin(child), end(child), -1);
}
};
vector <sufNode> sufTrie(1);
void suf_add_string(const string &newString, int tour_pos) {
int cur = 0;
for(char c:newString) {
int nxtCh = trch[(int)c];
if(sufTrie[cur].child[nxtCh] == -1) {
sufTrie[cur].child[nxtCh] = sz(sufTrie);
sufTrie.eb();
}
cur = sufTrie[cur].child[nxtCh];
}
sufTrie[cur].cnt++;
sufTrie[cur].id = tour_pos;
}
int suf_get_string(const string &f) {
int cur = 0;
for(char c:f) {
int nxtCh = trch[(int)c];
if(sufTrie[cur].child[nxtCh] == -1) {
sufTrie[cur].child[nxtCh] = sz(sufTrie);
sufTrie.eb();
}
cur = sufTrie[cur].child[nxtCh];
}
return cur;
}
void suf_get_size(int u) {
suf_st[u] = ++Time;
tour[Time] = u;
sub[u] = 1;
FOR(i, 0, 3) {
if(sufTrie[u].child[i] != -1) {
suf_get_size(sufTrie[u].child[i]);
sub[u] += sub[sufTrie[u].child[i]];
}
}
suf_en[u] = Time;
}
void suf_dfs_ans(int u) {
int bigCh = -1;
FOR(i, 0, 3) if(sufTrie[u].child[i] != -1) {
if(bigCh == -1 || sub[bigCh] < sub[sufTrie[u].child[i]]) {
bigCh = sufTrie[u].child[i];
}
}
FOR(i, 0, 3) if(sufTrie[u].child[i] != -1 && sufTrie[u].child[i] != bigCh) {
suf_dfs_ans(sufTrie[u].child[i]);
FOR(j, suf_st[sufTrie[u].child[i]], suf_en[sufTrie[u].child[i]]) {
if(sufTrie[tour[j]].id != -1) {
fwt.upd(sufTrie[tour[j]].id, -sufTrie[tour[j]].cnt);
}
}
/// delete from fenwick tree
}
if(bigCh != -1) suf_dfs_ans(bigCh);
FOR(i, 0, 3) if(sufTrie[u].child[i] != -1 && sufTrie[u].child[i] != bigCh) {
FOR(j, suf_st[sufTrie[u].child[i]], suf_en[sufTrie[u].child[i]]) {
if(sufTrie[tour[j]].id != -1) {
fwt.upd(sufTrie[tour[j]].id, sufTrie[tour[j]].cnt);
}
}
/// add to fenwick tree
};
// cout<<u<<" "<<sufTrie[u].id<<" "<<sufTrie[u].cnt<<'\n';
if(sufTrie[u].id != -1) fwt.upd(sufTrie[u].id, sufTrie[u].cnt);
/// add u to fenwick tree
for(auto [preN, id]:query[u]) {
queryAns[id] = fwt.getRange(st[preN], en[preN]);
// cout<<st[preN]<<" "<<en[preN]<<" "<<preN<<'\n';
}
}
void solve() {
cin >> n >> m;
trch['C'] = 0, trch['U'] = 1, trch['G'] = 2, trch['A'] = 3;
FOR(i, 1, n) {
cin >> s[i].fi;
s[i].se = pre_add_string(s[i].fi);
}
FOR(i, 1, m) {
string pre, suf; cin >> pre >> suf;
reverse(all(suf));
int idp = pre_get_string(pre),
ids = suf_get_string(suf);
query[ids].eb(idp, i);
}
pre_trie_dfs(0);
Time = 0;
FOR(i, 1, n) {
reverse(all(s[i].fi));
suf_add_string(s[i].fi, st[s[i].se]);
}
suf_get_size(0);
suf_dfs_ans(0);
FOR(i, 1, m) {
cout << queryAns[i] << '\n';
}
}
Compilation message
selling_rna.cpp: In function 'int32_t main()':
selling_rna.cpp:25:10: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
25 | freopen(task".inp", "r", stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
selling_rna.cpp:26:10: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
26 | freopen(task".out", "w", stdout);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
8 ms |
66908 KB |
Output is correct |
2 |
Correct |
8 ms |
67036 KB |
Output is correct |
3 |
Correct |
8 ms |
66908 KB |
Output is correct |
4 |
Correct |
8 ms |
66908 KB |
Output is correct |
5 |
Correct |
8 ms |
66908 KB |
Output is correct |
6 |
Correct |
8 ms |
67036 KB |
Output is correct |
7 |
Correct |
8 ms |
66908 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
115 ms |
144788 KB |
Output is correct |
2 |
Correct |
106 ms |
144596 KB |
Output is correct |
3 |
Correct |
61 ms |
125600 KB |
Output is correct |
4 |
Correct |
58 ms |
124796 KB |
Output is correct |
5 |
Correct |
134 ms |
183756 KB |
Output is correct |
6 |
Correct |
139 ms |
183696 KB |
Output is correct |
7 |
Correct |
36 ms |
74128 KB |
Output is correct |
8 |
Correct |
86 ms |
139172 KB |
Output is correct |
9 |
Correct |
75 ms |
131752 KB |
Output is correct |
10 |
Correct |
62 ms |
130732 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
17 ms |
67932 KB |
Output is correct |
2 |
Correct |
15 ms |
67872 KB |
Output is correct |
3 |
Correct |
17 ms |
67928 KB |
Output is correct |
4 |
Correct |
14 ms |
67420 KB |
Output is correct |
5 |
Correct |
15 ms |
67676 KB |
Output is correct |
6 |
Correct |
17 ms |
67860 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
8 ms |
66908 KB |
Output is correct |
2 |
Correct |
8 ms |
67036 KB |
Output is correct |
3 |
Correct |
8 ms |
66908 KB |
Output is correct |
4 |
Correct |
8 ms |
66908 KB |
Output is correct |
5 |
Correct |
8 ms |
66908 KB |
Output is correct |
6 |
Correct |
8 ms |
67036 KB |
Output is correct |
7 |
Correct |
8 ms |
66908 KB |
Output is correct |
8 |
Correct |
115 ms |
144788 KB |
Output is correct |
9 |
Correct |
106 ms |
144596 KB |
Output is correct |
10 |
Correct |
61 ms |
125600 KB |
Output is correct |
11 |
Correct |
58 ms |
124796 KB |
Output is correct |
12 |
Correct |
134 ms |
183756 KB |
Output is correct |
13 |
Correct |
139 ms |
183696 KB |
Output is correct |
14 |
Correct |
36 ms |
74128 KB |
Output is correct |
15 |
Correct |
86 ms |
139172 KB |
Output is correct |
16 |
Correct |
75 ms |
131752 KB |
Output is correct |
17 |
Correct |
62 ms |
130732 KB |
Output is correct |
18 |
Correct |
17 ms |
67932 KB |
Output is correct |
19 |
Correct |
15 ms |
67872 KB |
Output is correct |
20 |
Correct |
17 ms |
67928 KB |
Output is correct |
21 |
Correct |
14 ms |
67420 KB |
Output is correct |
22 |
Correct |
15 ms |
67676 KB |
Output is correct |
23 |
Correct |
17 ms |
67860 KB |
Output is correct |
24 |
Correct |
99 ms |
138560 KB |
Output is correct |
25 |
Correct |
103 ms |
141116 KB |
Output is correct |
26 |
Correct |
97 ms |
139580 KB |
Output is correct |
27 |
Correct |
59 ms |
117776 KB |
Output is correct |
28 |
Correct |
70 ms |
88336 KB |
Output is correct |
29 |
Correct |
41 ms |
72016 KB |
Output is correct |