Submission #1279921

#TimeUsernameProblemLanguageResultExecution timeMemory
1279921hotranminhky0405_Selling RNA Strands (JOI16_selling_rna)C++17
100 / 100
723 ms42312 KiB
#include <bits/stdc++.h> using namespace std; int chmap(char c){ if(c=='A') return 0; if(c=='G') return 1; if(c=='C') return 2; return 3; } struct Trie { struct Node { int next[4]; int end_id; Node(){ fill(begin(next), end(next), -1); end_id = -1; } }; vector<Node> nodes; Trie(){ nodes.emplace_back(); } int add_pattern(const string &s, int pat_id){ int cur = 0; for(char c: s){ int x = chmap(c); if(nodes[cur].next[x] == -1){ nodes[cur].next[x] = nodes.size(); nodes.emplace_back(); } cur = nodes[cur].next[x]; } if(nodes[cur].end_id == -1) nodes[cur].end_id = pat_id; return nodes[cur].end_id; } template<typename F> void visit_prefixes_in_string(const string &s, F visitor){ int cur = 0; for(char c: s){ int x = chmap(c); if(nodes[cur].next[x] == -1) return; cur = nodes[cur].next[x]; if(nodes[cur].end_id != -1){ visitor(nodes[cur].end_id); } } } template<typename F> void visit_suffixes_in_reversed_string(const string &rev_s, F visitor){ int cur = 0; for(char c: rev_s){ int x = chmap(c); if(nodes[cur].next[x] == -1) return; cur = nodes[cur].next[x]; if(nodes[cur].end_id != -1){ visitor(nodes[cur].end_id); } } } }; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int N, M; if(!(cin >> N >> M)) return 0; vector<string> S(N); for(int i=0;i<N;i++) cin >> S[i]; vector<pair<string,string>> queries(M); vector<string> Ps(M), Qs(M); for(int j=0;j<M;j++){ cin >> Ps[j] >> Qs[j]; queries[j] = {Ps[j], Qs[j]}; } unordered_map<string,int> pid_map; unordered_map<string,int> qid_map; pid_map.reserve(M*2); qid_map.reserve(M*2); int pid_cnt = 0, qid_cnt = 0; vector<int> q_to_pid(M), q_to_qid(M); for(int j=0;j<M;j++){ auto &p = Ps[j]; auto &q = Qs[j]; auto itp = pid_map.find(p); if(itp==pid_map.end()){ pid_map[p] = pid_cnt++; } auto itq = qid_map.find(q); if(itq==qid_map.end()){ qid_map[q] = qid_cnt++; } } Trie preTrie, sufTrie; vector<string> patternsP(pid_cnt); vector<string> patternsQ(qid_cnt); for(auto &kv : pid_map) patternsP[kv.second] = kv.first; for(auto &kv : qid_map) patternsQ[kv.second] = kv.first; for(int i=0;i<pid_cnt;i++){ preTrie.add_pattern(patternsP[i], i); } for(int i=0;i<qid_cnt;i++){ string rq = patternsQ[i]; reverse(rq.begin(), rq.end()); sufTrie.add_pattern(rq, i); } vector<vector<int>> listP(pid_cnt), listQ(qid_cnt); for(int i=0;i<N;i++){ preTrie.visit_prefixes_in_string(S[i], [&](int pid){ listP[pid].push_back(i); }); string revS = S[i]; reverse(revS.begin(), revS.end()); sufTrie.visit_suffixes_in_reversed_string(revS, [&](int qid){ listQ[qid].push_back(i); }); } for(int j=0;j<M;j++){ q_to_pid[j] = pid_map[Ps[j]]; q_to_qid[j] = qid_map[Qs[j]]; } unordered_map<unsigned long long,int> cache; cache.reserve(M*2); for(int j=0;j<M;j++){ int a = q_to_pid[j]; int b = q_to_qid[j]; unsigned long long key = ((unsigned long long)a << 32) | (unsigned long long)(unsigned)b; auto itc = cache.find(key); if(itc != cache.end()){ cout << itc->second << '\n'; continue; } auto &A = listP[a]; auto &B = listQ[b]; int ans = 0; if(A.size() <= B.size()){ for(int x: A){ if(binary_search(B.begin(), B.end(), x)) ++ans; } }else{ for(int x: B){ if(binary_search(A.begin(), A.end(), x)) ++ans; } } cache[key] = ans; cout << ans << '\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...