제출 #1222278

#제출 시각아이디문제언어결과실행 시간메모리
1222278giorgi123glmSelling RNA Strands (JOI16_selling_rna)C++20
60 / 100
1597 ms108044 KiB
#include <iostream> #include <unordered_map> #include <vector> #include <algorithm> #include <functional> #include <array> using namespace std; unordered_map <char, int> enhash = { {'A', 0}, {'U', 1}, {'G', 2}, {'C', 3} }; vector <char> dehash = { 'A', 'U', 'G', 'C' }; const int lim = 2e6 + 10; struct trie { int free_node = 1; vector <array <int, 4> > tree; vector <int> str_node; vector <char> node_col; vector <int> in; vector <int> out; trie (int num_str) { tree.resize (lim + 1); str_node.resize (num_str + 1); node_col.resize (lim + 1); node_col[0] = '.'; }; void add (string str, int ind) { int node = 0; for (int i = 0; i < str.size(); i++) { if (tree[node][enhash[str[i]]] == 0) { node_col[free_node] = str[i]; tree[node][enhash[str[i]]] = free_node++; } node = tree[node][enhash[str[i]]]; } str_node[ind] = node; } int traverse (string str) { int node = 0; for (int i = 0; i < str.size(); i++) { if (tree[node][enhash[str[i]]] == 0) return -1; node = tree[node][enhash[str[i]]]; } return node; } void calc_dfs () { in.clear(); out.clear(); in.resize (lim + 1); out.resize (lim + 1); int timer = 0; function <void(int,int)> dfs = [&](int p, int par)->void { in[p] = out[p] = ++timer; for (int& e : tree[p]) if (e != par && e != 0) dfs (e, p); out[p] = timer; }; dfs (0, 0); } void debug () { function <void(int,int,int)> dfs = [&](int p, int par, int dep)->void { cout << string (dep, '\t') << node_col[p] << ' ' << in[p] << ' ' << out[p] << '\n'; for (int& e : tree[p]) if (e != par && e != 0) dfs (e, p, dep + 1); }; dfs (0, 0, 0); } }; int main () { int N = 0, Q = 0; cin >> N >> Q; vector <string> in (N + 1); for (int i = 1; i <= N; i++) cin >> in[i]; trie preftrie (N + 1); trie sufftrie (N + 1); for (int i = 1; i <= N; i++) { preftrie.add (in[i], i); sufftrie.add ([](string str)->string { reverse (str.begin(), str.end()); return str; }(in[i]), i); } preftrie.calc_dfs(); sufftrie.calc_dfs(); // preftrie.debug(); // sufftrie.debug(); vector <pair <int, int> > status (N + 1); for (int i = 1; i <= N; i++) status[i] = { preftrie.in[preftrie.str_node[i]], sufftrie.in[sufftrie.str_node[i]] }; sort (status.begin() + 1, status.end()); vector <array <int, 4> > q_in (Q + 1); for (int i = 1; i <= Q; i++) { string a = "", b = ""; cin >> a >> b; reverse (b.begin(), b.end()); int prefnode = preftrie.traverse (a); int suffnode = sufftrie.traverse (b); if (prefnode == -1 || suffnode == -1) { q_in[i] = {-1, -1, -1, -1}; continue; } int& L1 = preftrie.in[prefnode], R1 = preftrie.out[prefnode]; int& L2 = sufftrie.in[suffnode], R2 = sufftrie.out[suffnode]; q_in[i] = { static_cast <int> (lower_bound (status.begin() + 1, status.end(), (pair <int, int>){L1, 0}) - status.begin()), static_cast <int> (lower_bound (status.begin() + 1, status.end(), (pair <int, int>){R1 + 1, 0}) - status.begin() - 1), L2, R2 }; } for (int i = 1; i <= Q; i++) { if (q_in[i][0] == -1) { cout << 0 << '\n'; continue; } int ans = 0; for (int j = q_in[i][0]; j <= q_in[i][1]; j++) if (q_in[i][2] <= status[j].second && status[j].second <= q_in[i][3]) ans++; cout << ans << '\n'; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...