Submission #201053

#TimeUsernameProblemLanguageResultExecution timeMemory
201053extraterrestrialExamination (JOI19_examination)C++14
43 / 100
929 ms109028 KiB
#include <bits/stdc++.h>
typedef long long ll;
typedef long double ld;
using namespace std;
#define F first
#define S second
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define SZ(x) (int)(x).size()
//#define int ll

struct query {
  int a, b, sum, id;
  query() {};
  query(int a, int b, int sum, int id) : a(a), b(b), sum(sum), id(id) {};
};

const int N = 1e5 + 10;
vector<int> vls[4 * N], fen[4 * N], xx[N];
int on[4 * N], ans[N];

void merge(int v) {
  int ptr1 = 0, ptr2 = 0;
  while (ptr1 < SZ(vls[2 * v]) && ptr2 < SZ(vls[2 * v + 1])) {
    if (vls[2 * v][ptr1] < vls[2 * v + 1][ptr2]) {
      if (vls[v].empty() || vls[v].back() != vls[2 * v][ptr1]) {
        vls[v].pb(vls[2 * v][ptr1]);
      }
      ptr1++;
    }
    else {
      if (vls[v].empty() || vls[v].back() != vls[2 * v + 1][ptr2]) {
        vls[v].pb(vls[2 * v + 1][ptr2]);
      }
      ptr2++; 
    }
  }
  while (ptr1 < SZ(vls[2 * v])) {
    if (vls[v].empty() || vls[v].back() != vls[2 * v][ptr1]) {
      vls[v].pb(vls[2 * v][ptr1]);
    }
    ptr1++;
  }
  while (ptr2 < SZ(vls[2 * v + 1])) {
    if (vls[v].empty() || vls[v].back() != vls[2 * v + 1][ptr2]) {
      vls[v].pb(vls[2 * v + 1][ptr2]);
    }
    ptr2++;
  }
}

void build(int v, int l, int r) {
  if (l == r) {
    vls[v] = xx[l];
    on[v] = 0;
    fen[v].resize(SZ(vls[v]) + 1);
    return;
  }
  int mid = (l + r) / 2;
  build(2 * v, l, mid);
  build(2 * v + 1, mid + 1, r);
  merge(v);
  on[v] = 0;
  fen[v].resize(SZ(vls[v]) + 1);
}

void update(int v, int l, int r, int x, int y) {
  on[v]++;
  int pos = upper_bound(all(vls[v]), y) - vls[v].begin();
  for (; pos <= SZ(vls[v]); pos += pos & (-pos)) {
    fen[v][pos]++;
  }
  if (l == r) {
    return;
  }
  int mid = (l + r) / 2;
  if (x <= mid) {
    update(2 * v, l, mid, x, y);
  }
  else {
    update(2 * v + 1, mid + 1, r, x, y);
  }
}

int get(int v, int l, int r, int a, int b, int y) {
  if (l > b || r < a) {
    return 0;
  }
  if (l >= a && r <= b) {
    int pos = lower_bound(all(vls[v]), y) - vls[v].begin(), res = on[v];
    for (; pos > 0; pos -= pos & (-pos)) {
      res -= fen[v][pos];
    }
    return res;
  }
  int mid = (l + r) / 2;
  return get(2 * v, l, mid, a, b, y) + get(2 * v + 1, mid + 1, r, a, b, y);
}

signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n, m;
  cin >> n >> m;
  vector<int> a(n), b(n), sa, sb, ss;
  for (int i = 0; i < n; i++) {
    cin >> a[i] >> b[i];
    sa.pb(a[i]);
    sb.pb(b[i]);
    ss.pb(a[i] + b[i]);
  }
  vector<query> que(m);
  for (int i = 0; i < m; i++) {
    cin >> que[i].a >> que[i].b >> que[i].sum;
    que[i].id = i;
    sa.pb(que[i].a);
    sb.pb(que[i].b);
    ss.pb(que[i].sum);
  }
  sort(all(sa));
  sort(all(sb));
  sort(all(ss));
  sa.resize(unique(all(sa)) - sa.begin());
  sb.resize(unique(all(sb)) - sb.begin());
  ss.resize(unique(all(ss)) - ss.begin());
  vector<vector<pair<int, int>>> add(SZ(ss));
  for (int i = 0; i < n; i++) {
    int cs = lower_bound(all(ss), a[i] + b[i]) - ss.begin();
    a[i] = upper_bound(all(sa), a[i]) - sa.begin();
    b[i] = upper_bound(all(sb), b[i]) - sb.begin();
    xx[a[i]].pb(b[i]);
    add[cs].pb({a[i], b[i]});
  }
  for (int i = 1; i <= SZ(sa); i++) {
    sort(all(xx[i]));
    xx[i].resize(unique(all(xx[i])) - xx[i].begin());
  }
  build(1, 1, SZ(sa));
  vector<vector<pair<pair<int, int>, int>>> check(SZ(ss));
  for (int i = 0; i < m; i++) {
    que[i].sum = lower_bound(all(ss), que[i].sum) - ss.begin();
    que[i].a = upper_bound(all(sa), que[i].a) - sa.begin();
    que[i].b = upper_bound(all(sb), que[i].b) - sb.begin();
    check[que[i].sum].pb(make_pair(make_pair(que[i].a, que[i].b), que[i].id));
  }
  for (int i = SZ(ss) - 1; i >= 0; i--) {
    for (auto it : add[i]) {
      update(1, 1, SZ(sa), it.F, it.S);
    }
    for (auto it : check[i]) {
      ans[it.S] = get(1, 1, SZ(sa), it.F.F, SZ(sa), it.F.S);
    }
  }
  for (int i = 0; i < m; i++) {
    cout << ans[i] << '\n';
  }
} 
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...