#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];
int lcp_pref[2*NM+5], lcp_suff[2*NM+5];
int sp_pref[LOG+5][2*NM+5], sp_suff[LOG+5][2*NM+5];
int val[2*NM+5], pos[2*NM+5], bit[2*NM+5];
int ans[NM+5];
int c(char ch){
if (ch == 'A') return 0;
if (ch == 'C') return 1;
if (ch == 'G') 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 build_sparse_table(){
for (int i = 1; i < N+M; i++){
sp_pref[0][i] = lcp_pref[i];
sp_suff[0][i] = lcp_suff[i];
}
for (int i = 1; i <= LOG; i++)
for (int j = 1; j+(1<<i)-1 < N+M; j++){
sp_pref[i][j] = min(sp_pref[i-1][j], sp_pref[i-1][j+(1<<(i-1))]);
sp_suff[i][j] = min(sp_suff[i-1][j], sp_suff[i-1][j+(1<<(i-1))]);
}
}
int get_lcp_pref(int l, int r){
if (l > r) return +inf;
if (l == r) return pref[l].size()-1;
r--;
int i = __lg(r-l+1);
return min(sp_pref[i][l], sp_pref[i][r-(1<<i)+1]);
}
int get_lcp_suff(int l, int r){
if (l > r) return +inf;
if (l == r) return suff[l].size()-1;
r--;
int i = __lg(r-l+1);
return min(sp_suff[i][l], sp_suff[i][r-(1<<i)+1]);
}
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++){
lcp_pref[i] = lcp(pref[id_pref[i]], pref[id_pref[i+1]]);
lcp_suff[i] = lcp(suff[id_suff[i]], suff[id_suff[i+1]]);
}
build_sparse_table();
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 (get_lcp_pref(mid, 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 (get_lcp_pref(i, 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 (get_lcp_suff(mid, 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 (get_lcp_suff(pos[i], 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
selling_rna.cpp: In function 'void process(std::string&, std::vector<int>&)':
selling_rna.cpp:27:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
27 | for (int i = 1; i <= S.size(); i++)
| ~~^~~~~~~~~~~
selling_rna.cpp: In function 'bool cmp_pref(int, int)':
selling_rna.cpp:46:10: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
46 | if (res == min(pref[x], pref[y]).size()-1){
| ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
selling_rna.cpp: In function 'bool cmp_suff(int, int)':
selling_rna.cpp:54:10: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
54 | if (res == min(suff[x], suff[y]).size()-1){
| ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
9 ms |
22356 KB |
Output is correct |
2 |
Correct |
9 ms |
22356 KB |
Output is correct |
3 |
Correct |
9 ms |
22412 KB |
Output is correct |
4 |
Correct |
9 ms |
22356 KB |
Output is correct |
5 |
Correct |
9 ms |
22356 KB |
Output is correct |
6 |
Correct |
9 ms |
22356 KB |
Output is correct |
7 |
Correct |
10 ms |
22356 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
108 ms |
52616 KB |
Output is correct |
2 |
Correct |
134 ms |
53704 KB |
Output is correct |
3 |
Correct |
125 ms |
53380 KB |
Output is correct |
4 |
Correct |
130 ms |
53708 KB |
Output is correct |
5 |
Correct |
72 ms |
42632 KB |
Output is correct |
6 |
Correct |
74 ms |
42804 KB |
Output is correct |
7 |
Correct |
155 ms |
58084 KB |
Output is correct |
8 |
Correct |
168 ms |
63540 KB |
Output is correct |
9 |
Correct |
159 ms |
63436 KB |
Output is correct |
10 |
Correct |
117 ms |
51064 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
97 ms |
44132 KB |
Output is correct |
2 |
Correct |
89 ms |
35404 KB |
Output is correct |
3 |
Correct |
99 ms |
39880 KB |
Output is correct |
4 |
Correct |
75 ms |
36496 KB |
Output is correct |
5 |
Correct |
77 ms |
35428 KB |
Output is correct |
6 |
Correct |
133 ms |
39896 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
9 ms |
22356 KB |
Output is correct |
2 |
Correct |
9 ms |
22356 KB |
Output is correct |
3 |
Correct |
9 ms |
22412 KB |
Output is correct |
4 |
Correct |
9 ms |
22356 KB |
Output is correct |
5 |
Correct |
9 ms |
22356 KB |
Output is correct |
6 |
Correct |
9 ms |
22356 KB |
Output is correct |
7 |
Correct |
10 ms |
22356 KB |
Output is correct |
8 |
Correct |
108 ms |
52616 KB |
Output is correct |
9 |
Correct |
134 ms |
53704 KB |
Output is correct |
10 |
Correct |
125 ms |
53380 KB |
Output is correct |
11 |
Correct |
130 ms |
53708 KB |
Output is correct |
12 |
Correct |
72 ms |
42632 KB |
Output is correct |
13 |
Correct |
74 ms |
42804 KB |
Output is correct |
14 |
Correct |
155 ms |
58084 KB |
Output is correct |
15 |
Correct |
168 ms |
63540 KB |
Output is correct |
16 |
Correct |
159 ms |
63436 KB |
Output is correct |
17 |
Correct |
117 ms |
51064 KB |
Output is correct |
18 |
Correct |
97 ms |
44132 KB |
Output is correct |
19 |
Correct |
89 ms |
35404 KB |
Output is correct |
20 |
Correct |
99 ms |
39880 KB |
Output is correct |
21 |
Correct |
75 ms |
36496 KB |
Output is correct |
22 |
Correct |
77 ms |
35428 KB |
Output is correct |
23 |
Correct |
133 ms |
39896 KB |
Output is correct |
24 |
Correct |
188 ms |
57936 KB |
Output is correct |
25 |
Correct |
254 ms |
64496 KB |
Output is correct |
26 |
Correct |
171 ms |
55756 KB |
Output is correct |
27 |
Correct |
199 ms |
57864 KB |
Output is correct |
28 |
Correct |
697 ms |
94916 KB |
Output is correct |
29 |
Correct |
604 ms |
79772 KB |
Output is correct |