Submission #1258816

#TimeUsernameProblemLanguageResultExecution timeMemory
1258816arashmemarSelling RNA Strands (JOI16_selling_rna)C++20
100 / 100
458 ms558176 KiB
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5 + 100, mod = 1e9 + 7, p = 701; long long int ptp[maxn]; vector <int> h[maxn]; string s[maxn]; int cnt; void init(string s, int ind) { h[ind].push_back(0); for (int i = 0;i < s.size();i++) { h[ind].push_back((h[ind][i] + ptp[i] * s[i] % mod) % mod); } return ; } bool cmp(int a, int b) { int l = 0, r = min(h[a].size(), h[b].size()); while (r - l - 1) { int mid = (l + r) / 2; if (h[a][mid] == h[b][mid]) { l = mid; } else { r = mid; } } if (r == min(h[a].size(), h[b].size())) { return h[a].size() < h[b].size(); } return s[a][l] < s[b][l]; } int a[maxn]; struct Node { int L, R, mid; vector <int> s; Node *lc, *rc; Node (int l, int r) { L = l, R = r, mid = (L + R) / 2, lc = rc = NULL; return ; } void init() { if (R - L == 1) { s.push_back(a[L]); return ; } lc = new Node(L, mid); rc = new Node(mid, R); lc->init(); rc->init(); int lptr = 0, rptr = 0; while (lptr != mid - L or rptr != R - mid) { if (rptr == R - mid or (lptr != mid - L and lc->s[lptr] < rc->s[rptr])) { s.push_back(lc->s[lptr]); lptr++; } else { s.push_back(rc->s[rptr]); rptr++; } } return ; } int get(int l, int r, int x, int y) { if (l >= r or l < L or r > R or x > y) { return 0; } if (l == L and R == r) { return upper_bound(s.begin(), s.end(), y) - lower_bound(s.begin(), s.end(), x); } int ret = 0; if (l < mid) { ret += lc->get(l, min(r, mid), x, y); } if (r > mid) { ret += rc->get(max(l, mid), r, x, y); } return ret; } }; struct T { int L, R, st, ft; vector <int> add; T* ch[21]; T() { L = maxn, R = 0, st = ft = 0; for (int i = 0;i < 21;i++) { ch[i] = NULL; } return ; } void insert(int ptr, int ind, int w) { L = min(L, w); R = max(R, w); if (ptr == s[ind].size()) { add.push_back(w); return ; } int g = s[ind][ptr] - 'A'; if (ch[g] == NULL) { ch[g] = new T(); } ch[g]->insert(ptr + 1, ind, w); return ; } pair <int, int> get(int ptr) { if (ptr == s[0].size()) { return {L, R}; } int g = s[0][ptr] - 'A'; if (ch[g] == NULL) { return {maxn, 0}; } return ch[g]->get(ptr + 1); } void dfs() { st = cnt + 1; for (auto o : add) { a[++cnt] = o; } for (int g = 0;g < 21;g++) { if (ch[g]) { ch[g]->dfs(); } } ft = cnt + 1; return ; } pair <int, int> getsf(int ptr, int ind) { if (ptr == s[ind].size()) { return {st, ft}; } int g = s[ind][ptr] - 'A'; if (ch[g]) { return ch[g]->getsf(ptr + 1, ind); } return {0, 0}; } }; int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); T *pre, *suf; pre = new T(); suf = new T(); ptp[0] = 1; for (int i = 1;i < maxn;i++) { ptp[i] = ptp[i - 1] * p % mod; } int n, m; cin >> n >> m; vector <int> tmp; for (int i = 1;i <= n;i++) { cin >> s[i]; init(s[i], i); tmp.push_back(i); } sort(tmp.begin(), tmp.end(), cmp); int it = 0; for (auto o : tmp) { pre->insert(0, o, ++it); reverse(s[o].begin(), s[o].end()); suf->insert(0, o, it); reverse(s[o].begin(), s[o].end()); } suf->dfs(); Node* root = new Node(1, cnt + 1); root->init(); for (int i = 1;i <= cnt;i++) { // cout << a[i] << ' '; } //cout << endl; while (m--) { cin >> s[0]; pair <int, int> tmp1 = pre->get(0); cin >> s[0]; reverse(s[0].begin(), s[0].end()); pair <int, int> tmp2 = suf->getsf(0, 0); //cout << tmp1.first << ' ' << tmp1.second << endl; //cout << tmp2.first << ' ' << tmp2.second << endl; cout << root->get(tmp2.first, tmp2.second, tmp1.first, tmp1.second) << '\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...