제출 #1125119

#제출 시각아이디문제언어결과실행 시간메모리
1125119votranngocvySelling RNA Strands (JOI16_selling_rna)C++20
100 / 100
564 ms309020 KiB
#include <bits/stdc++.h> using namespace std; #define pii pair<int,int> #define fi first #define se second const int N = 1e5 + 5; int n,m; string s[N],p[N],q[N]; struct Trie { struct Node { Node *child[4]; int idx; vector<int>vec; Node(int _num) { for (int i = 0; i < 4; i++) child[i] = NULL; idx = _num; vec.clear(); } }; int cur,numNode; Node *root; Trie(): cur(0) { numNode = 0; root = new Node(numNode); }; void add(string &s,int id) { Node *p = root; for (auto x: s) { int c = 0; if (x == 'A') c = 0; else if (x == 'G') c = 1; else if (x == 'C') c = 2; else if (x == 'U') c = 3; if (p -> child[c] == NULL) p -> child[c] = new Node(++numNode); p = p -> child[c]; (p -> vec).push_back(id); } } vector<int> get(string &s) { Node *p = root; for (auto x: s) { int c = 0; if (x == 'A') c = 0; else if (x == 'G') c = 1; else if (x == 'C') c = 2; else if (x == 'U') c = 3; if (p -> child[c] == NULL) { vector<int>nullVec; return nullVec; } p = p -> child[c]; } return (p -> vec); } int getNum(string &s) { Node *p = root; for (auto x: s) { int c = 0; if (x == 'A') c = 0; else if (x == 'G') c = 1; else if (x == 'C') c = 2; else if (x == 'U') c = 3; if (p -> child[c] == NULL) return 0; p = p -> child[c]; } return (p -> vec).size(); } int getIdx(string &s) { Node *p = root; for (auto x: s) { int c = 0; if (x == 'A') c = 0; else if (x == 'G') c = 1; else if (x == 'C') c = 2; else if (x == 'U') c = 3; if (p -> child[c] == NULL) return 0; p = p -> child[c]; } return (p -> idx); } vector<int>tin,tout; int timeDFS; void dfs(Node *u) { tin[u -> idx] = ++timeDFS; for (int i = 0; i < 4; i++) if (u -> child[i] != NULL) dfs(u -> child[i]); tout[u -> idx] = timeDFS; } void build() { tin.assign(numNode + 2,0); tout.assign(numNode + 2,0); timeDFS = 0; Node *p = root; dfs(p); } }; namespace sub2 { Trie pre,suf; int vis[5005]; void solve() { for (int i = 1; i <= n; i++) { pre.add(s[i],i); reverse(s[i].begin(),s[i].end()); suf.add(s[i],i); reverse(s[i].begin(),s[i].end()); } for (int i = 1; i <= m; i++) { vector<int>tmp1 = pre.get(p[i]); vector<int>tmp2 = suf.get(q[i]); for (auto x: tmp1) vis[x] = 1; int ans = 0; for (auto x: tmp2) if (vis[x]) ans++; cout << ans << "\n"; for (auto x: tmp1) vis[x] = 0; } } } namespace sub3 { Trie suf,T[350]; map<string,int>mp; bool check_condition() { int sumS = 0,sumP = 0,sumQ = 0; for (int i = 1; i <= n; i++) sumS += s[i].size(); for (int i = 1; i <= m; i++) { sumP += p[i].size(); sumQ += q[i].size(); } return (sumS <= 1e5 && sumP <= 1e5 && sumQ <= 1e5); } void solve() { for (int i = 1; i <= n; i++) { reverse(s[i].begin(),s[i].end()); suf.add(s[i],i); reverse(s[i].begin(),s[i].end()); } int num = 0; for (int i = 1; i <= m; i++) { if (mp.find(q[i]) != mp.end()) continue; mp[q[i]] = ++num; vector<int>tmp = suf.get(q[i]); for (auto x: tmp) T[num].add(s[x],x); } for (int i = 1; i <= m; i++) { int id = mp[q[i]]; cout << T[id].getNum(p[i]) << "\n"; } } } namespace sub4 { Trie pre,suf; const int maxN = 3e6 + 5; int ans[N],bit[maxN]; struct Data { int l,r,type,x,idx; }; vector<Data>vec; vector<pii>points; void update(int i,int x) { for (; i < maxN; i += i & (-i)) bit[i] += x; } int get(int i) { int ans = 0; for (; i > 0; i -= i & (-i)) ans += bit[i]; return ans; } void solve() { for (int i = 1; i <= n; i++) { pre.add(s[i],i); reverse(s[i].begin(),s[i].end()); suf.add(s[i],i); reverse(s[i].begin(),s[i].end()); } for (int i = 1; i <= m; i++) { pre.add(p[i],i); suf.add(q[i],i); } pre.build(); suf.build(); for (int i = 1; i <= n; i++) { int x = pre.getIdx(s[i]); reverse(s[i].begin(),s[i].end()); int y = suf.getIdx(s[i]); reverse(s[i].begin(),s[i].end()); x = pre.tin[x],y = suf.tin[y]; points.push_back({y,x}); } for (int i = 1; i <= m; i++) { int x = pre.getIdx(p[i]); int y = suf.getIdx(q[i]); vec.push_back({pre.tin[x],pre.tout[x],-1,suf.tin[y] - 1,i}); vec.push_back({pre.tin[x],pre.tout[x],1,suf.tout[y],i}); } sort(vec.begin(),vec.end(),[&](Data &a,Data &b) { return a.x < b.x; }); sort(points.begin(),points.end()); int j = 0; for (int i = 0; i < (int)vec.size(); i++) { while (j < (int)points.size() && points[j].fi <= vec[i].x) { update(points[j].se,1); j++; } ans[vec[i].idx] += vec[i].type * (get(vec[i].r) - get(vec[i].l - 1)); } for (int i = 1; i <= m; i++) cout << ans[i] << "\n"; } } signed main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> m; for (int i = 1; i <= n; i++) cin >> s[i]; for (int i = 1; i <= m; i++) { cin >> p[i] >> q[i]; reverse(q[i].begin(),q[i].end()); } //if (n <= 5000 && m <= 5000) sub2::solve(); //else if (sub3::check_condition()) sub3::solve(); //else sub4::solve(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...