Submission #1279961

#TimeUsernameProblemLanguageResultExecution timeMemory
1279961nguyenphucanhkhoiSelling RNA Strands (JOI16_selling_rna)C++17
0 / 100
245 ms229924 KiB
#include <bits/stdc++.h> using namespace std; struct Node { Node* child[4]; vector<int> pre; bool exist = false; Node() { for (int i = 0; i < 4; ++i) child[i] = nullptr; } }; struct Trie { Node* root; Trie() { root = new Node(); } // s must consist of letters 'A'..'D' only (we use 0..3) void add(const string &s, int idx) { Node* p = root; p->pre.push_back(idx); for (char ch : s) { int c = ch - 'A'; if (c < 0 || c > 3) return; // defensive (shouldn't happen) if (!p->child[c]) p->child[c] = new Node(); p = p->child[c]; p->pre.push_back(idx); } p->exist = true; } // sort pre vectors in the whole trie void sort_all(Node* p = nullptr) { if (p == nullptr) p = root; sort(p->pre.begin(), p->pre.end()); for (int i = 0; i < 4; ++i) if (p->child[i]) sort_all(p->child[i]); } // find node representing string s (or nullptr) Node* find_node(const string &s) { Node* p = root; for (char ch : s) { int c = ch - 'A'; if (c < 0 || c > 3) return nullptr; if (!p->child[c]) return nullptr; p = p->child[c]; } return p; } }; // map AGCU -> A,B,C,D so letters are 'A'..'D' string trans(const string &inp) { string out; out.reserve(inp.size()); for (char ch : inp) { if (ch == 'A') out.push_back('A'); else if (ch == 'G') out.push_back('B'); else if (ch == 'C') out.push_back('C'); else if (ch == 'U') out.push_back('D'); else { // if there are lowercase or T etc, you may want to handle or convert out.push_back(ch); // defensive } } return out; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); // optional file redir for local: // if (fopen("DELSEQ.INP", "r")) { freopen("DELSEQ.INP", "r", stdin); freopen("DELSEQ.OUT", "w", stdout); } int n, m; if (!(cin >> n >> m)) return 0; Trie tPref, tSuf; // tPref -> prefixes; tSuf -> reversed strings (to handle suffixes) vector<string> arr(n + 1); for (int i = 1; i <= n; ++i) { string tmp; cin >> tmp; string tr = trans(tmp); arr[i] = tr; // add to prefix trie with index i tPref.add(tr, i); // add reversed string to suffix trie with index i reverse(tr.begin(), tr.end()); tSuf.add(tr, i); } // sort all pre vectors so lower_bound/upper_bound work tPref.sort_all(); tSuf.sort_all(); while (m--) { string p, q; cin >> p >> q; p = trans(p); q = trans(q); // find prefix node in tPref Node* nodeP = tPref.find_node(p); if (nodeP == nullptr || nodeP->pre.empty()) { cout << 0 << '\n'; continue; } int L = nodeP->pre.front(); // minimum original index with prefix p int R = nodeP->pre.back(); // maximum original index with prefix p // find suffix node in reversed trie (we must reverse q) reverse(q.begin(), q.end()); Node* nodeQ = tSuf.find_node(q); if (nodeQ == nullptr || nodeQ->pre.empty()) { cout << 0 << '\n'; continue; } // count how many indices in nodeQ->pre fall into [L, R] auto &vec = nodeQ->pre; int lp = int(lower_bound(vec.begin(), vec.end(), L) - vec.begin()); int rp = int(upper_bound(vec.begin(), vec.end(), R) - vec.begin()); cout << (rp - lp) << '\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...