Submission #128823

#TimeUsernameProblemLanguageResultExecution timeMemory
128823godwindSelling RNA Strands (JOI16_selling_rna)C++14
100 / 100
468 ms187036 KiB
#pragma GCC optimize("Ofast")
/*#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,popcnt,abm,mmx,tune=native")*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <stdio.h>
#include <cstdio>
#include <math.h>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <deque>
#include <random>
#include <iomanip>
#include <bitset>
                         
using namespace std;
                         
template<typename T> void uin(T &a, T b) {
    if (b < a) {
        a = b;
    }
}
                         
template<typename T> void uax(T &a, T b) {
    if (b > a) {
        a = b;
    }
}
   
#define ghost signed
#define left left228
#define right right228
#define prev prev228
#define list list228
  
const int N = 100 * 1000 + 228;
 
int code(char c) {
    if (c == 'A') return 0;
    if (c == 'C') return 1;
    if (c == 'G') return 2;
    return 3;
}
 
struct node
{
    int nxt[4];
    vector<int> list;
    int mn, mx;
    node() {
        nxt[0] = nxt[1] = nxt[2] = nxt[3] = 0;
        list.clear();
        mn = mx = 0;
    }
};
 
vector< node > t1, t;
int counter1 = 0, counter = 0;
 
void init() {
    t1.push_back(node());
    t.push_back(node());
}
 
void add1(string s, int i) {
    int now = 0;
    int c = 0;
    for (char C : s) {
        c = code(C);
        if (!t1[now].nxt[c]) {
            t1[now].nxt[c] = ++counter1;
            t1.push_back(node());
        }
        now = t1[now].nxt[c];
        if (t1[now].mn == 0) {
            t1[now].mn = t1[now].mx = i;
        } else {
            uin(t1[now].mn, i);
            uax(t1[now].mx, i);
        }
    }
}
 
pair<int, int> get_range(string s) {
    int now = 0;
    int c = 0;
    for (char C : s) {
        c = code(C);
        if (!t1[now].nxt[c]) return {0, 0};
        now = t1[now].nxt[c];
    }
    return {t1[now].mn, t1[now].mx};
}
 
void add(string s, int i) {
    int now = 0;
    int c = 0;
    for (char C : s) {
        c = code(C);
        if (!t[now].nxt[c]) {
            t[now].nxt[c] = ++counter;
            t.push_back(node());
        }
        now = t[now].nxt[c];
        t[now].list.push_back(i);
    }
}
 
int get(string s, int l, int r) {
    int now = 0;
    int c = 0;
    for (char C : s) {
        c = code(C);
        if (!t[now].nxt[c]) return 0;
        now = t[now].nxt[c];
    }
    int up = upper_bound(t[now].list.begin(), t[now].list.end(), r) - t[now].list.begin();
    int down = lower_bound(t[now].list.begin(), t[now].list.end(), l) - t[now].list.begin();
    return up - down;
}
 
string str[N];
int n, m;
 
 
ghost main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) {
        cin >> str[i];
    }
    sort(str + 1, str + n + 1);
    init();
    for (int i = 1; i <= n; ++i) {
        add1(str[i], i);
        reverse(str[i].begin(), str[i].end());
        add(str[i], i);
    }
    for (int it = 0; it < m; ++it) {
        string p, q;
        cin >> p >> q;
        reverse(q.begin(), q.end());
        pair<int, int> range = get_range(p);
        if (range.first == 0) {
            cout << 0 << '\n';
            continue;
        }
        int l = range.first, r = range.second;
        cout << get(q, l, r) << '\n';
    }
    return 0;
} // kek ;
  
  
/*
  
8
1 2 4 1 3 4 1 2
2 2 3 2 2 3 2 2
  
*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...