답안 #434976

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
434976 2021-06-22T17:18:46 Z model_code 사탕 분배 (IOI21_candies) C++17
100 / 100
783 ms 35772 KB
#include "candies.h"

#include <algorithm>
#include <vector>

struct SegTree {
  int n;
  std::vector<long long> mini, maxi, sums, vals;

  SegTree(int _n): n(_n) {
    mini.assign(n * 2, 0);
    maxi.assign(n * 2, 0);
    sums.assign(n * 2, 0);
    vals.assign(n, 0);
  }

  void update(int idx, int l, int r, int x, int val) {
    if (l == x && r == x + 1) {
      mini[idx] = maxi[idx] = sums[idx] = val;
      return;
    }

    int mid = (l + r) >> 1;
    int lidx = idx + 1, ridx = idx + (mid - l) * 2;
    if (x < mid) update(lidx, l, mid, x, val);
    else update(ridx, mid, r, x, val);
    mini[idx] = std::min(mini[lidx] + sums[ridx], mini[ridx]);
    maxi[idx] = std::max(maxi[lidx] + sums[ridx], maxi[ridx]);
    sums[idx] = sums[lidx] + sums[ridx];
  }

  std::tuple<int, int, int> query(int idx, int l, int r,
                                  int sufmin, int sufmax, int sufsum, int c) {
    if (l + 1 == r) {
      return std::make_tuple(std::min(1LL * sufmin, sufsum + mini[idx]),
                             std::max(1LL * sufmax, sufsum + maxi[idx]), l);
    }

    int mid = (l + r) >> 1;
    int lidx = idx + 1, ridx = idx + (mid - l) * 2;
    long long nsufmin = std::min(1LL * sufmin, sufsum + mini[ridx]), 
              nsufmax = std::max(1LL * sufmax, sufsum + maxi[ridx]),
              nsufsum = sufsum + sums[ridx];

    if (nsufmax - nsufmin > c) return query(ridx, mid, r, sufmin, sufmax, sufsum, c);
    return query(lidx, l, mid, nsufmin, nsufmax, nsufsum, c);
  }

  void update(int x, int val) {
    vals[x] = val;
    update(0, 0, n, x, val);
  }

  // Find smallest suffix such that max - min > c.
  // If no such suffix, the whole range is returned.
  // Returns (max, min, i)
  std::tuple<int, int, int> query(int c) {
    return query(0, 0, n, 0, 0, 0, c);
  }

  inline int at(int x) { return vals[x]; }
};

std::vector<int> distribute_candies(std::vector<int> c, std::vector<int> l,
                                    std::vector<int> r, std::vector<int> v) {
  int n = c.size(), q = v.size();
  std::vector<std::vector<std::pair<int, int>>> queriesL(n), queriesR(n);
  for (int i = 0; i < q; ++i) {
    queriesL[l[i]].emplace_back(i, v[i]);
    queriesR[r[i]].emplace_back(i, v[i]);
  }

  std::vector<int> s(n);
  SegTree tree(q);
  for (int i = 0; i < n; ++i) {
    for (auto [idx, val] : queriesL[i]) {
      tree.update(idx, -val);
    }

    auto [mini, maxi, idx] = tree.query(c[i]);
    if (maxi - mini <= c[i]) {
      s[i] = -mini;
    } else {
      if (tree.at(idx) < 0) {
        s[i] = c[i] - maxi;
      } else {
        s[i] = -mini;
      }
    }

    for (auto [idx, val] : queriesR[i]) {
      tree.update(idx, 0);
    }
  }

  return s;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
3 Correct 2 ms 460 KB Output is correct
4 Correct 2 ms 460 KB Output is correct
5 Correct 3 ms 588 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 706 ms 35620 KB Output is correct
2 Correct 748 ms 35644 KB Output is correct
3 Correct 651 ms 35772 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 332 KB Output is correct
2 Correct 314 ms 21612 KB Output is correct
3 Correct 84 ms 12300 KB Output is correct
4 Correct 575 ms 35624 KB Output is correct
5 Correct 588 ms 35636 KB Output is correct
6 Correct 585 ms 35532 KB Output is correct
7 Correct 642 ms 35648 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 332 KB Output is correct
3 Correct 162 ms 19384 KB Output is correct
4 Correct 90 ms 12204 KB Output is correct
5 Correct 238 ms 30840 KB Output is correct
6 Correct 246 ms 30844 KB Output is correct
7 Correct 246 ms 30732 KB Output is correct
8 Correct 239 ms 30728 KB Output is correct
9 Correct 248 ms 30772 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
3 Correct 2 ms 460 KB Output is correct
4 Correct 2 ms 460 KB Output is correct
5 Correct 3 ms 588 KB Output is correct
6 Correct 706 ms 35620 KB Output is correct
7 Correct 748 ms 35644 KB Output is correct
8 Correct 651 ms 35772 KB Output is correct
9 Correct 1 ms 332 KB Output is correct
10 Correct 314 ms 21612 KB Output is correct
11 Correct 84 ms 12300 KB Output is correct
12 Correct 575 ms 35624 KB Output is correct
13 Correct 588 ms 35636 KB Output is correct
14 Correct 585 ms 35532 KB Output is correct
15 Correct 642 ms 35648 KB Output is correct
16 Correct 1 ms 204 KB Output is correct
17 Correct 1 ms 332 KB Output is correct
18 Correct 162 ms 19384 KB Output is correct
19 Correct 90 ms 12204 KB Output is correct
20 Correct 238 ms 30840 KB Output is correct
21 Correct 246 ms 30844 KB Output is correct
22 Correct 246 ms 30732 KB Output is correct
23 Correct 239 ms 30728 KB Output is correct
24 Correct 248 ms 30772 KB Output is correct
25 Correct 1 ms 204 KB Output is correct
26 Correct 94 ms 12196 KB Output is correct
27 Correct 324 ms 21640 KB Output is correct
28 Correct 783 ms 35756 KB Output is correct
29 Correct 664 ms 35636 KB Output is correct
30 Correct 651 ms 35536 KB Output is correct
31 Correct 616 ms 35636 KB Output is correct
32 Correct 593 ms 35560 KB Output is correct