Submission #839483

#TimeUsernameProblemLanguageResultExecution timeMemory
839483daoquanglinh2007Selling RNA Strands (JOI16_selling_rna)C++17
100 / 100
845 ms67144 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long const int NM = 1e5, MOD = 1e9+7, LOG = 17, inf = 1e9+7; int N, M; string P[2*NM+5], Q[2*NM+5]; vector <int> pref[2*NM+5], suff[2*NM+5]; int id_pref[2*NM+5], id_suff[2*NM+5], val[2*NM+5], pos[2*NM+5], bit[2*NM+5], ans[NM+5]; int c(char ch){ if (ch == 'A') return 0; if (ch == 'G') return 1; if (ch == 'C') return 2; return 3; } void process(string &S, vector <int> &f){ f.resize(S.size()+1); f[0] = 0; for (int i = 1; i <= S.size(); i++) f[i] = ((ll)f[i-1]*4+c(S[i-1]))%MOD; } int lcp(vector <int> &f1, vector <int> &f2){ int l = 1, r = min(f1.size(), f2.size())-1, res = 0; while (l <= r){ int mid = (l+r)/2; if (f1[mid] == f2[mid]){ res = mid; l = mid+1; } else r = mid-1; } return res; } bool cmp_pref(int x, int y){ int res = lcp(pref[x], pref[y]); if (res == min(pref[x], pref[y]).size()-1){ return pref[x].size() < pref[y].size(); } return c(P[x][res]) < c(P[y][res]); } bool cmp_suff(int x, int y){ int res = lcp(suff[x], suff[y]); if (res == min(suff[x], suff[y]).size()-1){ return suff[x].size() < suff[y].size(); } return c(Q[x][res]) < c(Q[y][res]); } void update(int p, int v){ while (p <= N+M){ bit[p] += v; p += p & (-p); } } int sum(int p){ int res = 0; while (p > 0){ res += bit[p]; p -= p & (-p); } return res; } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> N >> M; for (int i = 1; i <= N; i++){ cin >> P[i]; Q[i] = P[i]; reverse(Q[i].begin(), Q[i].end()); process(P[i], pref[i]); process(Q[i], suff[i]); } for (int i = N+1; i <= N+M; i++){ cin >> P[i] >> Q[i]; reverse(Q[i].begin(), Q[i].end()); process(P[i], pref[i]); process(Q[i], suff[i]); } for (int i = 1; i <= N+M; i++) id_pref[i] = id_suff[i] = i; sort(id_pref+1, id_pref+1+N+M, cmp_pref); sort(id_suff+1, id_suff+1+N+M, cmp_suff); for (int i = 1; i <= N+M; i++) val[id_suff[i]] = i; for (int i = 1; i <= N+M; i++) pos[i] = val[id_pref[i]]; int curL = 1, curR = 0; for (int i = 1; i <= N+M; i++){ if (id_pref[i] <= N) continue; int k = pref[id_pref[i]].size()-1, L = i, R = i; int l = 1, r = i-1; while (l <= r){ int mid = (l+r)/2; if (lcp(pref[id_pref[mid]], pref[id_pref[i]]) >= k){ L = mid; r = mid-1; } else l = mid+1; } l = i+1, r = N+M; while (l <= r){ int mid = (l+r)/2; if (lcp(pref[id_pref[i]], pref[id_pref[mid]]) >= k){ R = mid; l = mid+1; } else r = mid-1; } while (curL > L){ curL--; if (id_pref[curL] <= N) update(pos[curL], 1); } while (curR < R){ curR++; if (id_pref[curR] <= N) update(pos[curR], 1); } while (curL < L){ if (id_pref[curL] <= N) update(pos[curL], -1); curL++; } while (curR > R){ if (id_pref[curR] <= N) update(pos[curR], -1); curR--; } k = suff[id_suff[pos[i]]].size()-1; int resl = pos[i], resr = pos[i]; l = 1, r = pos[i]-1; while (l <= r){ int mid = (l+r)/2; if (lcp(suff[id_suff[mid]], suff[id_suff[pos[i]]]) >= k){ resl = mid; r = mid-1; } else l = mid+1; } l = pos[i]+1, r = N+M; while (l <= r){ int mid = (l+r)/2; if (lcp(suff[id_suff[pos[i]]], suff[id_suff[mid]]) >= k){ resr = mid; l = mid+1; } else r = mid-1; } ans[id_pref[i]-N] = sum(resr)-sum(resl-1); } for (int i = 1; i <= M; i++) cout << ans[i] << '\n'; return 0; }

Compilation message (stderr)

selling_rna.cpp: In function 'void process(std::string&, std::vector<int>&)':
selling_rna.cpp:23:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   23 |  for (int i = 1; i <= S.size(); i++)
      |                  ~~^~~~~~~~~~~
selling_rna.cpp: In function 'bool cmp_pref(int, int)':
selling_rna.cpp:42:10: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   42 |  if (res == min(pref[x], pref[y]).size()-1){
      |      ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
selling_rna.cpp: In function 'bool cmp_suff(int, int)':
selling_rna.cpp:50:10: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   50 |  if (res == min(suff[x], suff[y]).size()-1){
      |      ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...