답안 #786047

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
786047 2023-07-17T23:16:39 Z tvladm2009 Selling RNA Strands (JOI16_selling_rna) C++17
100 / 100
213 ms 201804 KB
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int L = 2000000 + 7;
const int N = (int) 1e5 + 7;

int aib[L];

void add(int i, int x) {
  while (i < L) {
    aib[i] += x;
    i += i & -i;
  }
}

int get(int i) {
  int sol = 0;
  while (i >= 1) {
    sol += aib[i];
    i -= i & -i;
  }
  return sol;
}

int decode(char ch) {
  if (ch == 'A') return 0;
  if (ch == 'G') return 1;
  if (ch == 'C') return 2;
  if (ch == 'U') return 3;
  assert(false);
}

struct TrieNode {
  TrieNode* kids[4];
  int first;
  int last;
  vector<int> guys;

  TrieNode() {
    for (int i = 0; i < 4; i++) {
      kids[i] = nullptr;
    }
  }
};

void addToTrie(TrieNode* root, string s, int index) {
  TrieNode* current = root;
  for (auto &ch : s) {
    int decoded = decode(ch);
    if (!current->kids[decoded]) {
      current->kids[decoded] = new TrieNode;
    }
    current = current->kids[decoded];
  }
  current->guys.push_back(index);
}

void prepTrie(TrieNode* root, int inverse[]) {
  int index = 0;
  function<void(TrieNode*)> dfs = [&] (TrieNode* current) {
    current->first = ++index;
    for (auto &i : current->guys) {
      inverse[i] = index;
    }
    for (int j = 0; j < 4; j++) {
      if (current->kids[j]) {
        dfs(current->kids[j]);
      }
    }
    current->last = index;
  };
  dfs(root);
}

pair<int, int> getInterval(TrieNode* root, string s) {
  TrieNode* current = root;
  for (auto &ch : s) {
    int decoded = decode(ch);
    if (!current->kids[decoded]) {
      return {1, 0};
    }
    current = current->kids[decoded];
  }
  return {current->first, current->last};
}

TrieNode* root1 = new TrieNode;
TrieNode* root2 = new TrieNode;
int x[N];
int y[N];

struct BBox {
  int xmin;
  int ymin;
  int xmax;
  int ymax;
  int index;
};

struct Question {
  int x;
  int y;
  int coef;
  int index;
};

bool operator < (Question a, Question b) {
  return a.x < b.x;
}

bool cmp(int i, int j) {
  return x[i] < x[j];
}

int solPrint[N];

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

  ///freopen("input", "r", stdin);

  int n, q;
  cin >> n >> q;

  vector<int> ord;
  for (int i = 1; i <= n; i++) {
    string s, revs;
    ord.push_back(i);
    cin >> s;
    revs = s;
    reverse(revs.begin(), revs.end());

    addToTrie(root1, s, i);
    addToTrie(root2, revs, i);
  }
  sort(ord.begin(), ord.end(), cmp);

  prepTrie(root1, x);
  prepTrie(root2, y);

  vector<Question> questions;

  for (int iq = 1; iq <= q; iq++) {
    string pref, suf;
    cin >> pref >> suf;

    reverse(suf.begin(), suf.end());

    auto xx = getInterval(root1, pref);
    auto yy = getInterval(root2, suf);


    if (xx.first > xx.second || yy.first > yy.second) {
      continue;
    }

    int x1 = xx.first, x2 = xx.second;
    int y1 = yy.first, y2 = yy.second;

    questions.push_back({x2, y2, +1, iq});
    questions.push_back({x2, y1 - 1, -1, iq});
    questions.push_back({x1 - 1, y2, -1, iq});
    questions.push_back({x1 - 1, y1 - 1, +1, iq});
  }

  sort(questions.begin(), questions.end());
  sort(ord.begin(), ord.end(), cmp);

  int it = 0;
  for (auto &question : questions) {
    while (it < n && x[ord[it]] <= question.x) {
      add(y[ord[it]], +1);
      it++;
    }
    int sol = get(question.y);
    sol *= question.coef;
    solPrint[question.index] += sol;
  }

  for (int iq = 1; iq <= q; iq++) {
    cout << solPrint[iq] << "\n";
  }


  return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 336 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Correct 1 ms 340 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 1 ms 340 KB Output is correct
7 Correct 1 ms 340 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 156 ms 166136 KB Output is correct
2 Correct 162 ms 158504 KB Output is correct
3 Correct 162 ms 157348 KB Output is correct
4 Correct 143 ms 149984 KB Output is correct
5 Correct 210 ms 198780 KB Output is correct
6 Correct 213 ms 201804 KB Output is correct
7 Correct 34 ms 6860 KB Output is correct
8 Correct 146 ms 121708 KB Output is correct
9 Correct 136 ms 102972 KB Output is correct
10 Correct 99 ms 97672 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 29 ms 6164 KB Output is correct
2 Correct 20 ms 4056 KB Output is correct
3 Correct 26 ms 6180 KB Output is correct
4 Correct 20 ms 5736 KB Output is correct
5 Correct 20 ms 4068 KB Output is correct
6 Correct 27 ms 6116 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 336 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Correct 1 ms 340 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 1 ms 340 KB Output is correct
7 Correct 1 ms 340 KB Output is correct
8 Correct 156 ms 166136 KB Output is correct
9 Correct 162 ms 158504 KB Output is correct
10 Correct 162 ms 157348 KB Output is correct
11 Correct 143 ms 149984 KB Output is correct
12 Correct 210 ms 198780 KB Output is correct
13 Correct 213 ms 201804 KB Output is correct
14 Correct 34 ms 6860 KB Output is correct
15 Correct 146 ms 121708 KB Output is correct
16 Correct 136 ms 102972 KB Output is correct
17 Correct 99 ms 97672 KB Output is correct
18 Correct 29 ms 6164 KB Output is correct
19 Correct 20 ms 4056 KB Output is correct
20 Correct 26 ms 6180 KB Output is correct
21 Correct 20 ms 5736 KB Output is correct
22 Correct 20 ms 4068 KB Output is correct
23 Correct 27 ms 6116 KB Output is correct
24 Correct 145 ms 138576 KB Output is correct
25 Correct 154 ms 140756 KB Output is correct
26 Correct 135 ms 136320 KB Output is correct
27 Correct 137 ms 131264 KB Output is correct
28 Correct 121 ms 31912 KB Output is correct
29 Correct 70 ms 13512 KB Output is correct