Submission #1297319

#TimeUsernameProblemLanguageResultExecution timeMemory
1297319cspercivalSelling RNA Strands (JOI16_selling_rna)C++20
100 / 100
688 ms493108 KiB
// Template generated by Clank #include<bits/stdc++.h> using namespace std; #define st first #define nd second #define all(x) x.begin(), x.end() #define BOOST cin.tie(NULL); ios_base::sync_with_stdio(false); // #define int ll typedef long long ll; pair<int,int> pzero = {-1,-1}; struct Node{ int next[30] = {0}; int nw = 0; int l = 1e9, r = 0; vector<int> ids; }; struct Trie{ int root = 1; int prectr = 1; vector<Node> t; Trie(){ t.resize(2); } void add_string(string &s, int id){ int idx = root; // cout << t[idx].next[0] << " lol\n"; for(auto c : s){ if(!t[idx].next[c - 'A']){ t[idx].next[c - 'A'] = (int)t.size(); t.emplace_back(); } idx = t[idx].next[c - 'A']; } t[idx].ids.push_back(id); t[idx].nw++; } int dfs(int idx, vector<pair<int,int>> &labels){ // static int prectr = 1; t[idx].l = prectr; for(int i : t[idx].ids){ labels[i].st = prectr++; t[idx].r = labels[i].st; } for(int i = 0; i < 30; i++){ if(t[idx].next[i] != 0){ t[idx].r = max(t[idx].r, dfs(t[idx].next[i], labels)); } } return t[idx].r; } pair<int,int> get_lim(string &s){ int idx = root; // cout << s << "\n"; for(int i = 0; i < (int)s.size(); i++){ if(t[idx].next[s[i] - 'A'] == 0) return pzero; idx = t[idx].next[s[i] - 'A']; // cout << idx << "\n"; } return {t[idx].l - 1, t[idx].r}; } }; struct SegTree{ int n; int shift = 1; vector<int> t; SegTree(int inn) : n(inn){ while(shift < n) shift <<= 1; t.resize(2 * shift); } void update(int idx, int val){ for(idx += shift; idx >= 1; idx >>= 1){ t[idx] += val; } } int query(int l, int r){ int sum = 0; for(l += shift, r += shift; l < r; l >>= 1, r >>= 1){ if(l&1) sum += t[l++]; if(r&1) sum += t[--r]; } return sum; } }; void compute_rect(int n, vector<pair<int,int>> &labels, vector<pair<pair<int,int>, pair<int,int>>> &queries, map<pair<int,int>, int> &rect){ vector<pair<pair<int,int>, int>> points; for(int i = 0; i < n; i++){ points.push_back({labels[i], -1}); } for(auto i : queries){ if(i.st == pzero || i.nd == pzero) continue; points.push_back({{i.st.st, i.nd.st}, 0}); points.push_back({{i.st.st, i.nd.nd}, 0}); points.push_back({{i.st.nd, i.nd.st}, 0}); points.push_back({{i.st.nd, i.nd.nd}, 0}); } SegTree tree(n + 5); sort(all(points)); for(auto p : points){ if(p.nd == 0){ rect[p.st] = tree.query(0, p.st.nd + 1); } else { tree.update(p.st.nd, abs(p.nd)); } } } int32_t main(){ BOOST; int n, m; cin >> n >> m; string notes; Trie pre; Trie suf; for(int i = 0; i < n; i++){ cin >> notes; pre.add_string(notes,i); reverse(all(notes)); suf.add_string(notes, i); } vector<pair<int,int>> labels(n); suf.dfs(1, labels); for(int i = 0; i < n; i++) swap(labels[i].st, labels[i].nd); pre.dfs(1, labels); vector<pair<pair<int,int>, pair<int,int>>> queries; string sp, ss; for(int i = 0; i < m; i++){ cin >> sp >> ss; reverse(all(ss)); queries.push_back({pre.get_lim(sp), suf.get_lim(ss)}); } // for(int i = 0; i < n; i++){ // cout << labels[i].st << " - " << labels[i].nd << "\n"; // } // cout << "\n"; // for(auto i : queries){ // cout << i.st.st << " " << i.st.nd << " " << i.nd.st << " " << i.nd.nd << "\n"; // } // cout << labels << "\n"; // cout << queries << "\n"; map<pair<int,int>, int> rectangles; compute_rect(n, labels, queries, rectangles); // for(auto i : rectangles){ // cout << i.st.st << " " << i.st.nd << " - " << i.nd << "\n"; // } int sum = 0; for(auto i : queries){ sum = 0; if(i.st == pzero || i.nd == pzero){ cout << 0 << "\n"; continue; } sum += rectangles[{i.st.st, i.nd.st}]; sum -= rectangles[{i.st.st, i.nd.nd}]; sum -= rectangles[{i.st.nd, i.nd.st}]; sum += rectangles[{i.st.nd, i.nd.nd}]; cout << sum << "\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...