Submission #708954

#TimeUsernameProblemLanguageResultExecution timeMemory
708954JohannSelling RNA Strands (JOI16_selling_rna)C++14
100 / 100
269 ms211028 KiB
#include "bits/stdc++.h"
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vpii;
typedef vector<bool> vb;
typedef vector<vb> vvb;
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()

struct segtree
{
    int size;
    vi arr;
    vb active;
    void init(int n)
    {
        size = 1;
        while (size < n)
            size *= 2;
        arr.assign(2 * size, 0);
        active.assign(2 * size, false);
    }
    void doInc(int x, int amount)
    {
        if (x < size || active[x])
            arr[x] += amount;
    }
    void propagate(int x)
    {
        if (x < size)
        {
            doInc(2 * x, arr[x]);
            doInc(2 * x + 1, arr[x]);
            arr[x] = 0;
        }
    }
    void increment(int l, int r) { increment(l, r, 1, 0, size); }
    void increment(int l, int r, int x, int lx, int rx)
    {
        if (l <= lx && rx <= r)
        {
            doInc(x, 1);
            return;
        }
        if (r <= lx || rx <= l)
            return;
        int m = (lx + rx) / 2;
        increment(l, r, 2 * x, lx, m);
        increment(l, r, 2 * x + 1, m, rx);
    }
    void setState(int x, bool state) { setState(x, state, 1, 0, size); }
    void setState(int i, bool state, int x, int lx, int rx)
    {
        propagate(x);
        if (rx - lx == 1)
        {
            active[x] = state;
            return;
        }
        int m = (lx + rx) / 2;
        if (i < m)
            setState(i, state, 2 * x, lx, m);
        else
            setState(i, state, 2 * x + 1, m, rx);
    }
    int query(int i) { return query(i, 1, 0, size); }
    int query(int i, int x, int lx, int rx)
    {
        propagate(x);
        if (rx - lx == 1)
            return arr[x];
        int m = (lx + rx) / 2;
        if (i < m)
            return query(i, 2 * x, lx, m);
        else
            return query(i, 2 * x + 1, m, rx);
    }
};

vvi S;        // Sortiment von der Company
vvi P, Q;     // Prefixes and suffixes
vi Qin, Qout; // in idx and out idx for the range sums
segtree seg;

struct node
{
    int idx = 0; // of this node
    node *children[4] = {nullptr, nullptr, nullptr, nullptr};
    vi fixe; // suffixe or prefixe
    vi S;    // together with suffixes there are sorting
};
struct trie
{
    node *root = new node();
    void insert(vi &word, int id, bool type) { insert(root, 0, word, id, type); }
    void insert(node *r, int idx, vi &word, int id, int type)
    { // id to append to the fixe (type 0) and S (type 1)
        if (idx == sz(word))
        {
            if (type == 0)
                r->fixe.push_back(id);
            else
                r->S.push_back(id);
            return;
        }
        int next = word[idx];
        if (r->children[next] == nullptr)
            r->children[next] = new node();

        insert(r->children[next], idx + 1, word, id, type);
    }
};

trie Tsuff, Tpref;

void dfsInit(node *r, int &idx)
{
    for (int q : r->fixe)
        Qin[q] = ++idx;
    r->idx = idx; // knowing the correct prefix idx

    for (int i = 0; i < 4; ++i)
        if (r->children[i] != nullptr)
            dfsInit(r->children[i], idx);

    for (int q : r->fixe)
        Qout[q] = ++idx;
}

void answer(node *r, vi &word)
{
    int idx = 0;
    int i = 0;
    while (r != nullptr)
    {
        idx = r->idx;
        if (i >= sz(word))
            break;
        r = r->children[word[i++]];
    }
    seg.increment(0, idx + 1);
}

void dfsAnswer(node *r)
{
    for (int qid : r->fixe)
    {
        seg.setState(Qin[qid], true);
        seg.setState(Qout[qid], true);
    }
    for (int sid : r->S)
    {
        answer(Tpref.root, S[sid]);
    }

    for (int i = 0; i < 4; ++i)
        if (r->children[i] != nullptr)
            dfsAnswer(r->children[i]);

    for (int qid : r->fixe)
    {
        seg.setState(Qin[qid], false);
        seg.setState(Qout[qid], false);
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    int N, M;
    cin >> N >> M;

    S.resize(N);
    string rna, kundeP, kundeQ;
    vi decode(128);
    decode['A'] = 0, decode['C'] = 1, decode['G'] = 2, decode['U'] = 3;

    for (int i = 0; i < N; ++i)
    {
        cin >> rna;
        for (char c : rna)
            S[i].push_back(decode[c]);
        reverse(all(S[i]));
        Tsuff.insert(S[i], i, 1);
        reverse(all(S[i]));
    }

    P.resize(M), Q.resize(M);
    for (int i = 0; i < M; ++i)
    {
        cin >> kundeP >> kundeQ;
        for (char c : kundeP)
            P[i].push_back(decode[c]);
        Tpref.insert(P[i], i, 0);

        for (char c : kundeQ)
            Q[i].push_back(decode[c]);
        reverse(all(Q[i]));
        Tsuff.insert(Q[i], i, 0);
    }

    int idx = 0;
    Qin.resize(M), Qout.resize(M);
    dfsInit(Tpref.root, idx);
    ++idx;

    seg.init(idx);

    dfsAnswer(Tsuff.root);

    for (int q = 0; q < M; ++q)
        cout << seg.query(Qin[q]) - seg.query(Qout[q]) << "\n";

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...