#include <iostream>
#include <string>
#include <vector>
using namespace std;
const int NMAX = 1e5;
const int QMAX = 1e5;
struct Node {
Node* sons[4];
vector <int> wordList;
pair <int, int> wordRange;
Node() {
for(int i = 0; i < 4; i++) {
sons[i] = NULL;
}
}
};
int N, Q;
string s;
Node *pref = new Node, *suf = new Node;
int GetSon(char s) {
if(s == 'A') {
return 0;
} else if(s == 'G') {
return 1;
} else if(s == 'C') {
return 2;
}
return 3;
}
void InsertPref(Node* node, int index, int id) {
if(index == (int)s.size()) {
node-> wordList.push_back(id);
return;
}
int son = GetSon(s[index]);
if(node-> sons[son] == NULL) {
node-> sons[son] = new Node;
}
InsertPref(node-> sons[son], index + 1, id);
}
void InsertSuf(Node* node, int index, int id) {
if(index == -1) {
node-> wordList.push_back(id);
return;
}
int son = GetSon(s[index]);
if(node-> sons[son] == NULL) {
node-> sons[son] = new Node;
}
InsertSuf(node-> sons[son], index - 1, id);
}
string pr, sf;
vector<int> wordsWithPref, wordsWithSuf;
vector <int> prefOrder;
vector <int> sufOrder;
void DfsPref(Node* root) {
if(root == NULL) {
return ;
}
root->wordRange.first = (int)prefOrder.size() + 1;
for(int word : root-> wordList) {
prefOrder.push_back(word);
}
for(int j = 0; j < 4; j++) {
DfsPref(root-> sons[j]);
}
root->wordRange.second = (int)prefOrder.size();
}
void DfsSuf(Node* root) {
if(root == NULL) {
return ;
}
root->wordRange.first = (int)sufOrder.size() + 1;
for(int word : root-> wordList) {
sufOrder.push_back(word);
}
for(int j = 0; j < 4; j++) {
DfsSuf(root-> sons[j]);
}
root->wordRange.second = (int)sufOrder.size();
}
pair<int, int> GetRangePref(Node* root, int index) {
if(root == NULL) {
return {-1, -1};
}
if(index == (int)pr.size()) {
return root-> wordRange;
}
int son = GetSon(pr[index]);
return GetRangePref(root-> sons[son], index + 1);
}
pair<int, int> GetRangeSuf(Node* root, int index) {
if(root == NULL) {
return {-1, -1};
}
if(index == -1) {
return root-> wordRange;
}
int son = GetSon(sf[index]);
return GetRangeSuf(root-> sons[son], index - 1);
}
int posSuf[NMAX + 2], matchLine[NMAX + 2];
struct LineQuery {
int l, r, ind;
};
vector<LineQuery> lineQueries[NMAX + 2];
int k, ansLine[2 * QMAX + 2];
pair <int, int> qrl[QMAX + 2];
int ans[QMAX + 2];
int aib[NMAX + 2];
inline int LSB(int x) {
return x & (-x);
}
void Update(int pos) {
for(int i = pos; i <= N; i += LSB(i)) {
aib[i]++;
}
}
int Query(int pos) {
int ans = 0;
for(int i = pos; i > 0; i -= LSB(i)) {
ans += aib[i];
}
return ans;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cin >> N >> Q;
for(int i = 1; i <= N; i++) {
cin >> s;
InsertPref(pref, 0, i);
InsertSuf(suf, (int)s.size() - 1, i);
}
DfsPref(pref);
DfsSuf(suf);
for(int i = 1; i <= Q; i++) {
cin >> pr >> sf;
pair <int, int> rangePref = GetRangePref(pref, 0);
pair <int, int> rangeSuf = GetRangeSuf(suf, (int)sf.size() - 1);
if(rangePref.first == -1 || rangeSuf.first == -1 || (rangePref.first > rangePref.second) || (rangeSuf.first > rangeSuf.second)) {
ans[i] = 0;
} else {
++k;
lineQueries[rangePref.second].push_back({rangeSuf.first, rangeSuf.second, k});
++k;
lineQueries[rangePref.first - 1].push_back({rangeSuf.first, rangeSuf.second, k});
qrl[i] = {k - 1, k};
}
}
for(int i = 0; i < N; i++) {
posSuf[sufOrder[i]] = i + 1;
}
for(int i = 0; i < N; i++) {
matchLine[i + 1] = posSuf[prefOrder[i]];
}
for(int i = 1; i <= N; i++) {
Update(matchLine[i]);
for(LineQuery lq : lineQueries[i]) {
ansLine[lq.ind] = Query(lq.r) - Query(lq.l - 1);
}
}
for(int i = 1; i <= Q; i++) {
if(qrl[i].first != 0) {
ans[i] = ansLine[qrl[i].first] - ansLine[qrl[i].second];
}
}
for(int i = 1; i <= Q; i++) {
cout << ans[i] << '\n';
}
return 0;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
2796 KB |
Output is correct |
2 |
Correct |
2 ms |
2796 KB |
Output is correct |
3 |
Correct |
2 ms |
2796 KB |
Output is correct |
4 |
Correct |
2 ms |
2796 KB |
Output is correct |
5 |
Correct |
2 ms |
2796 KB |
Output is correct |
6 |
Correct |
2 ms |
2796 KB |
Output is correct |
7 |
Correct |
2 ms |
2796 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
297 ms |
161516 KB |
Output is correct |
2 |
Correct |
233 ms |
153580 KB |
Output is correct |
3 |
Correct |
244 ms |
159468 KB |
Output is correct |
4 |
Correct |
242 ms |
152072 KB |
Output is correct |
5 |
Correct |
352 ms |
196332 KB |
Output is correct |
6 |
Correct |
304 ms |
199240 KB |
Output is correct |
7 |
Correct |
38 ms |
8940 KB |
Output is correct |
8 |
Correct |
223 ms |
121068 KB |
Output is correct |
9 |
Correct |
193 ms |
102892 KB |
Output is correct |
10 |
Correct |
164 ms |
97772 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
27 ms |
7452 KB |
Output is correct |
2 |
Correct |
22 ms |
6508 KB |
Output is correct |
3 |
Correct |
27 ms |
7092 KB |
Output is correct |
4 |
Correct |
21 ms |
6128 KB |
Output is correct |
5 |
Correct |
21 ms |
6124 KB |
Output is correct |
6 |
Correct |
27 ms |
6792 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
2796 KB |
Output is correct |
2 |
Correct |
2 ms |
2796 KB |
Output is correct |
3 |
Correct |
2 ms |
2796 KB |
Output is correct |
4 |
Correct |
2 ms |
2796 KB |
Output is correct |
5 |
Correct |
2 ms |
2796 KB |
Output is correct |
6 |
Correct |
2 ms |
2796 KB |
Output is correct |
7 |
Correct |
2 ms |
2796 KB |
Output is correct |
8 |
Correct |
297 ms |
161516 KB |
Output is correct |
9 |
Correct |
233 ms |
153580 KB |
Output is correct |
10 |
Correct |
244 ms |
159468 KB |
Output is correct |
11 |
Correct |
242 ms |
152072 KB |
Output is correct |
12 |
Correct |
352 ms |
196332 KB |
Output is correct |
13 |
Correct |
304 ms |
199240 KB |
Output is correct |
14 |
Correct |
38 ms |
8940 KB |
Output is correct |
15 |
Correct |
223 ms |
121068 KB |
Output is correct |
16 |
Correct |
193 ms |
102892 KB |
Output is correct |
17 |
Correct |
164 ms |
97772 KB |
Output is correct |
18 |
Correct |
27 ms |
7452 KB |
Output is correct |
19 |
Correct |
22 ms |
6508 KB |
Output is correct |
20 |
Correct |
27 ms |
7092 KB |
Output is correct |
21 |
Correct |
21 ms |
6128 KB |
Output is correct |
22 |
Correct |
21 ms |
6124 KB |
Output is correct |
23 |
Correct |
27 ms |
6792 KB |
Output is correct |
24 |
Correct |
215 ms |
134508 KB |
Output is correct |
25 |
Correct |
231 ms |
136556 KB |
Output is correct |
26 |
Correct |
220 ms |
132716 KB |
Output is correct |
27 |
Correct |
216 ms |
132588 KB |
Output is correct |
28 |
Correct |
142 ms |
33156 KB |
Output is correct |
29 |
Correct |
72 ms |
14376 KB |
Output is correct |