Submission #276510

#TimeUsernameProblemLanguageResultExecution timeMemory
276510spdskatrSelling RNA Strands (JOI16_selling_rna)C++14
100 / 100
323 ms224096 KiB
#include <iostream> #include <cstdlib> #include <algorithm> #include <string> #include <vector> #include <utility> #define SZ (1<<21) #define fi first #define se second using namespace std; struct entry { int i, l, r, f, a; }; int N, M, ppos[100005], spos[100005], ans[100005]; string S[100005], P[100005], Q[100005]; vector<int> sw[2000005]; vector<entry> qu; char bruh[] = { 'A', 'C', 'G', 'U' }; struct Trie { int ch[2000005][4], cnt = 2, sz[2000005], ind[2000005], cnt2; vector<int> occ[2000005]; void build(int s) { int cur = 1; for (char c : S[s]) { for (int i = 0; i < 4; i++) { if (c == bruh[i]) { if (ch[cur][i] == 0) { ch[cur][i] = cnt++; } cur = ch[cur][i]; } } } occ[cur].push_back(s); } void dfs(int x, int *p) { ind[x] = cnt2++; sz[x] = 1; for (int v : occ[x]) p[v] = ind[x]; for (int i = 0; i < 4; i++) { if (ch[x][i]) { dfs(ch[x][i], p); sz[x] += sz[ch[x][i]]; } } } int query(const string &s) { int cur = 1; for (char c : s) { for (int i = 0; i < 4; i++) { if (c == bruh[i]) { if (ch[cur][i] == 0) { return 0; } cur = ch[cur][i]; } } } return cur; } } tp, ts; struct Segtree { int st[1<<22]; void seg_inc(int i) { for (st[i += SZ] += 1; i > 1; i >>= 1) st[i>>1] = st[i] + st[i^1]; } int seg_sum(int l, int r) { int res = 0; for (l += SZ, r += SZ; l < r; l >>= 1, r >>= 1) { if (l&1) res += st[l++]; if (r&1) res += st[--r]; } return res; } } st1; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> N >> M; for (int i = 0; i < N; i++) { cin >> S[i]; tp.build(i); reverse(S[i].begin(), S[i].end()); ts.build(i); } tp.dfs(1, ppos); ts.dfs(1, spos); for (int i = 0; i < N; i++) { //printf("Point at (%d, %d)\n", ppos[i], spos[i]); sw[ppos[i]].push_back(spos[i]); } for (int i = 0; i < M; i++) { cin >> P[i] >> Q[i]; reverse(Q[i].begin(), Q[i].end()); int pn = tp.query(P[i]); int sn = ts.query(Q[i]); int pl = tp.ind[pn]; int pr = tp.ind[pn] + tp.sz[pn]; int sl = ts.ind[sn]; int sr = ts.ind[sn] + ts.sz[sn]; //printf("Query %d: [%d, %d), [%d, %d)\n", i, pl, pr, sl, sr); qu.push_back({ pl-1, sl, sr, -1, i }); qu.push_back({ pr-1, sl, sr, 1, i }); } sort(qu.begin(), qu.end(), [](entry l, entry r) { return l.i < r.i; }); int cur = 0; for (entry e : qu) { while (cur <= e.i) { for (int x : sw[cur]) { //printf("Incrementing %d, %d\n", cur, x); st1.seg_inc(x); } cur++; } ans[e.a] += e.f * st1.seg_sum(e.l, e.r); } for (int i = 0; i < M; i++) { cout << ans[i] << "\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...