답안 #436570

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
436570 2021-06-24T15:59:14 Z flashmt 사탕 분배 (IOI21_candies) C++17
8 / 100
1000 ms 49320 KB
#include <bits/stdc++.h>
using namespace std;
const long long oo = 1LL << 60;

struct SegmentTree
{
  int low, mid, high;
  long long save;
  pair<long long, int> minVal, maxVal;
  SegmentTree *l, *r;

  SegmentTree(int low, int high): low(low), high(high)
  {
    mid = (low + high) / 2;
    save = 0;
    minVal = maxVal = {0, low};
    if (low != high)
    {
      l = new SegmentTree(low, mid);
      r = new SegmentTree(mid + 1, high);
    }
  }

  void pushDown()
  {
    if (save)
    {
      l->minVal.first += save;
      l->maxVal.first += save;
      l->save += save;
      r->minVal.first += save;
      r->maxVal.first += save;
      r->save += save;
      save = 0;
    }
  }

  void update(int x, int y, long long value)
  {
    if (low == x && high == y)
    {
      minVal.first += value;
      maxVal.first += value;
      save += value;
    }
    else
    {
      pushDown();
      if (x <= mid)
        l->update(x, min(y, mid), value);
      if (mid < y)
        r->update(max(x, mid + 1), y, value);

      minVal = min(l->minVal, r->minVal);
      maxVal = max(l->maxVal, r->maxVal);
    }
  }

  int find(long long diff, long long curMax, long long curMin)
  {
    if (max(maxVal.first, curMax) - min(minVal.first, curMin) < diff)
      return -1;
    if (low == high)
      return low;
    pushDown();
    if (max(r->maxVal.first, curMax) - min(r->minVal.first, curMin) >= diff)
      return r->find(diff, curMax, curMin);
    return l->find(diff, max(curMax, r->maxVal.first), min(curMin, r->minVal.first));
  }

  pair<long long, int> getMin(int x, int y)
  {
    if (low == x && high == y)
      return minVal;
    pushDown();
    auto u = x <= mid ? l->getMin(x, min(y, mid)) : make_pair(oo, -1);
    auto v = mid < y ? r->getMin(max(x, mid + 1), y) : make_pair(oo, -1);
    return min(u, v);
  }

  pair<long long, int> getMax(int x, int y)
  {
    if (low == x && high == y)
      return maxVal;
    pushDown();
    auto u = x <= mid ? l->getMax(x, min(y, mid)) : make_pair(-oo, -1);
    auto v = mid < y ? r->getMax(max(x, mid + 1), y) : make_pair(-oo, -1);
    return max(u, v);
  }
};


vector<int> distribute_candies(vector<int> c, vector<int> l, vector<int> r, vector<int> v)
{
  int n = c.size(), q = l.size();

  vector<vector<int>> queries(n, vector<int>());
  for (int i = 0; i < q; i++)
  {
    queries[l[i]].push_back(i + 1);
    if (r[i] + 1 < n)
      queries[r[i] + 1].push_back(-i - 1);
  }

  SegmentTree *tree = new SegmentTree(0, q);
  vector<int> ans;
  for (int i = 0; i < n; i++)
  {
    for (int id : queries[i])
      if (id < 0) tree->update(-id, q, -v[-id - 1]);
      else tree->update(id, q, v[id - 1]);

    int u = tree->find(c[i], -oo, oo); // reach min or max in [u, q]
    auto [vLast, _] = tree->getMin(q, q);
    if (u < 0) ans.push_back(vLast);
    else
    {
      auto [vMin, idMin] = tree->getMin(u, q);
      auto [vMax, idMax] = tree->getMax(u, q);
      if (idMax > idMin) ans.push_back(c[i] - vMax + vLast);
      else ans.push_back(vLast - vMin);
    }
  }

  return ans;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Incorrect 1 ms 204 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 898 ms 49260 KB Output is correct
2 Correct 936 ms 49320 KB Output is correct
3 Correct 1000 ms 49308 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 204 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
3 Incorrect 143 ms 37152 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Incorrect 1 ms 204 KB Output isn't correct
3 Halted 0 ms 0 KB -