Submission #1280845

#TimeUsernameProblemLanguageResultExecution timeMemory
1280845courte_.sanmaSelling RNA Strands (JOI16_selling_rna)C++20
100 / 100
269 ms210508 KiB
#include <bits/stdc++.h> using namespace std; using pii = pair<int,int>; const int INF = 2000000000; struct Node { int child[4]; vector<int> ids; int l, r; Node() { memset(child, -1, sizeof(child)); ids.clear(); l = INF; r = 0; } }; struct Trie { vector<Node> node; Trie() { node.emplace_back(); } // root = 0 int new_node() { node.emplace_back(); return (int)node.size() - 1; } void add(const string &s, int id, int type) { // update root to support empty query if (type == 2) node[0].ids.push_back(id); else { node[0].l = min(node[0].l, id); node[0].r = max(node[0].r, id); } int p = 0; for (char ch : s) { int x = ch - '0'; if (x < 0 || x > 3) return; // defensive if (node[p].child[x] == -1) node[p].child[x] = new_node(); p = node[p].child[x]; if (type == 2) node[p].ids.push_back(id); else { node[p].l = min(node[p].l, id); node[p].r = max(node[p].r, id); } } } pii get_range(const string &s) { int p = 0; for (char ch : s) { int x = ch - '0'; if (x < 0 || x > 3) return {-1,-1}; int nxt = node[p].child[x]; if (nxt == -1) return {-1,-1}; p = nxt; } if (node[p].l > node[p].r) return {-1,-1}; return {node[p].l, node[p].r}; } vector<int> get_ids(const string &s) { int p = 0; for (char ch : s) { int x = ch - '0'; if (x < 0 || x > 3) return {}; int nxt = node[p].child[x]; if (nxt == -1) return {}; p = nxt; } return node[p].ids; } }; void compress_string(string &s) { for (char &c : s) { if (c=='A' || c=='a') c='0'; else if (c=='G' || c=='g') c='1'; else if (c=='U' || c=='u') c='2'; else if (c=='C' || c=='c') c='3'; } } int main() { ios::sync_with_stdio(false); cin.tie(NULL); int n, q; if (!(cin >> n >> q)) return 0; vector<string> orig(n+1); for (int i = 1; i <= n; ++i) cin >> orig[i]; vector<pair<string,int>> arr; arr.reserve(n); for (int i = 1; i <= n; ++i) { string t = orig[i]; compress_string(t); arr.emplace_back(t, i); } sort(arr.begin(), arr.end(), [](const pair<string,int>& a, const pair<string,int>& b){ return a.first < b.first; }); vector<string> s_sorted(n+1); vector<int> pos(n+1); for (int i = 0; i < n; ++i) { s_sorted[i+1] = arr[i].first; pos[arr[i].second] = i+1; } Trie pre, suf; for (int i = 1; i <= n; ++i) { pre.add(s_sorted[i], i, 1); } for (int orig_idx = 1; orig_idx <= n; ++orig_idx) { string t = arr[ pos[orig_idx] - 1 ].first; } for (int i = 1; i <= n; ++i) { string t = orig[i]; compress_string(t); reverse(t.begin(), t.end()); suf.add(t, pos[i], 2); } for (auto &nd : suf.node) { if (!nd.ids.empty()) sort(nd.ids.begin(), nd.ids.end()); } while (q--) { string P, Q; cin >> P >> Q; compress_string(P); compress_string(Q); pii range = pre.get_range(P); if (range.first == -1) { cout << 0 << '\n'; continue; } reverse(Q.begin(), Q.end()); vector<int> vec = suf.get_ids(Q); if (vec.empty()) { cout << 0 << '\n'; continue; } int L = lower_bound(vec.begin(), vec.end(), range.first) - vec.begin(); int R = upper_bound(vec.begin(), vec.end(), range.second) - vec.begin(); cout << (R - L) << '\n'; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...