Submission #1111677

#TimeUsernameProblemLanguageResultExecution timeMemory
1111677Zero_OPSelling RNA Strands (JOI16_selling_rna)C++14
100 / 100
221 ms70448 KiB
#include <bits/stdc++.h> using namespace std; mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); int random(int l, int r){ return uniform_int_distribution<int>(l, r)(rng); } int code(char c){ if(c == 'A') return 0; if(c == 'G') return 1; if(c == 'U') return 2; if(c == 'C') return 3; assert(false); } struct Trie{ struct Node{ int next[4]; Node(){ memset(next, -1, sizeof(next)); } }; vector<Node> nd; Trie() { nd.emplace_back(); } int size(){ return (int)nd.size(); } void add(const string& s){ int u = 0; for(auto ch : s){ int c = code(ch); if(nd[u].next[c] == -1){ nd[u].next[c] = size(); nd.emplace_back(); } u = nd[u].next[c]; } } int timer_dfs; vector<int> tin, tout; void dfsTree(int u){ tin[u] = ++timer_dfs; for(int i = 0; i < 4; ++i){ if(nd[u].next[i] != -1){ dfsTree(nd[u].next[i]); } } tout[u] = timer_dfs; } void construct_tree(){ timer_dfs = 0; tin.resize(size()); tout.resize(size()); dfsTree(0); assert(timer_dfs == size()); } pair<int, int> get_subtree(int u){ assert(u < size()); return make_pair(tin[u], tout[u]); } int get(const string& s){ int u = 0; for(auto ch : s){ int c = code(ch); if(nd[u].next[c] == -1) return -1; u = nd[u].next[c]; } return u; } }; struct Fenwick{ vector<int> bit; Fenwick(int n) : bit(n + 1, 0) {} void update(int id, int val){ for(; id < (int)bit.size(); id += id & (-id)) bit[id] += val; } int query(int l, int r){ int sum = 0; --l; // cout << l << ' ' << r << '\n'; for(; l > 0; l -= l & (-l)) sum -= bit[l]; for(; r > 0; r -= r & (-r)) sum += bit[r]; return sum; } }; int main(){ // ios_base::sync_with_stdio(0); cin.tie(0); // if(fopen("task.inp", "r")){ // freopen("task.inp", "r", stdin); // freopen("task.out", "w", stdout); // } int N, Q; cin >> N >> Q; vector<string> S(N); Trie prefix_trie, suffix_trie; for(int i = 0; i < N; ++i){ cin >> S[i]; prefix_trie.add(S[i]); reverse(S[i].begin(), S[i].end()); suffix_trie.add(S[i]); } prefix_trie.construct_tree(); suffix_trie.construct_tree(); struct event{ int x, type, l, r, id; bool operator < (const event& o){ return (x == o.x ? type < o.type : x < o.x); } }; vector<event> events; for(int i = 0; i < N; ++i){ reverse(S[i].begin(), S[i].end()); int x = prefix_trie.get(S[i]); reverse(S[i].begin(), S[i].end()); int y = suffix_trie.get(S[i]); events.push_back({prefix_trie.tin[x], -1, suffix_trie.tin[y], suffix_trie.tin[y], i}); } vector<int> ans(Q); for(int i = 0; i < Q; ++i){ string p, q; cin >> p >> q; reverse(q.begin(), q.end()); int i1 = prefix_trie.get(p), i2 = suffix_trie.get(q); if(i1 == -1 || i2 == -1){ ans[i] = 0; continue; } int l1, r1, l2, r2; tie(l1, r1) = prefix_trie.get_subtree(i1); tie(l2, r2) = suffix_trie.get_subtree(i2); events.push_back({l1 - 1, 0, l2, r2, i}); events.push_back({r1, 1, l2, r2, i}); } sort(events.begin(), events.end()); Fenwick ft(suffix_trie.size()); for(auto e : events){ if(e.type == -1){ ft.update(e.l, +1); } else{ if(e.type == 0) ans[e.id] -= ft.query(e.l, e.r); else ans[e.id] += ft.query(e.l, e.r); } } for(int i = 0; i < Q; ++i) cout << ans[i] << '\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...