답안 #414306

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
414306 2021-05-30T10:05:49 Z Alex_tz307 Sails (IOI07_sails) C++17
100 / 100
157 ms 3144 KB
#include <bits/stdc++.h>

using namespace std;
using int64 = long long;

struct SegTree {
  int Size;
  vector<int> tree, lazy;

  SegTree(int N) {
    Size = 1;
    while (Size < N)
      Size <<= 1;
    tree.resize(Size << 1);
    lazy.resize(Size << 1);
  }

  void push(int x) {
    if (lazy[x] == 0)
      return;
    for (int i = 0; i < 2; ++i) {
      int son = x << 1 | i;
      tree[son] += lazy[x];
      lazy[son] += lazy[x];
    }
    lazy[x] = 0;
  }

  void update(int x, int lx, int rx, int st, int dr) {
    if (st <= lx && rx <= dr) {
      ++tree[x], ++lazy[x];
      return;
    }
    push(x);
    int mid = (lx + rx) >> 1, lSon = x << 1, rSon = x << 1 | 1;
    if (st <= mid)
      update(lSon, lx, mid, st, dr);
    if (mid < dr)
      update(rSon, mid + 1, rx, st, dr);
    tree[x] = min(tree[lSon], tree[rSon]);
  }

  int get_val(int x, int lx, int rx, int poz) {
    if (lx == rx)
      return tree[x];
    push(x);
    int mid = (lx + rx) >> 1;
    if (poz <= mid)
      return get_val(x << 1, lx, mid, poz);
    return get_val(x << 1 | 1, mid + 1, rx, poz);
  }

  int first_lower(int x, int lx, int rx, int val) {
    if (lx == rx)
      return lx;
    push(x);
    int mid = (lx + rx) >> 1, lSon = x << 1, rSon = x << 1 | 1;
    if (tree[lSon] < val)
      return first_lower(lSon, lx, mid, val);
    return first_lower(rSon, mid + 1, rx, val);
  }

  int first_equal(int x, int lx, int rx, int val) {
    if (lx == rx)
      return lx;
    push(x);
    int mid = (lx + rx) >> 1, lSon = x << 1, rSon = x << 1 | 1;
    if (tree[lSon] <= val)
      return first_equal(lSon, lx, mid, val);
    return first_equal(rSon, mid + 1, rx, val);
  }
};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  int n;
  cin >> n;
  vector<pair<int,int>> m(n);
  for (auto &p : m)
    cin >> p.first >> p.second;
  sort(m.begin(), m.end());
  int H = m.back().first;
  SegTree tree(H);
  for (auto p : m) {
    int h, k;
    tie(h, k) = p;
    int val = tree.get_val(1, 1, H, h - k + 1);
    if (tree.tree[1] < val) {
      int nxt = tree.first_lower(1, 1, H, val);
      if (nxt <= h) {
        tree.update(1, 1, H, nxt, h);
        k -= h - nxt + 1;
        if (k == 0)
          continue;
      }
    }
    int poz = tree.first_equal(1, 1, H, val);
    tree.update(1, 1, H, poz, poz + k - 1);
  }
  int64 ans = 0;
  for (int h = 1; h <= H; ++h) {
    int64 sails = tree.get_val(1, 1, H, h);
    ans += (sails * (sails - 1)) >> 1;
  }
  cout << ans << '\n';
  return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 332 KB Output is correct
2 Correct 8 ms 2388 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 876 KB Output is correct
2 Correct 35 ms 560 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 34 ms 972 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 74 ms 1740 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 129 ms 2948 KB Output is correct
2 Correct 115 ms 2892 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 157 ms 3020 KB Output is correct
2 Correct 59 ms 3056 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 155 ms 3144 KB Output is correct
2 Correct 86 ms 1620 KB Output is correct