답안 #706872

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
706872 2023-03-08T02:25:18 Z nhuang685 원숭이와 사과 나무 (IZhO12_apple) C++17
0 / 100
432 ms 262144 KB
/**
 * @author nhuang685
 * @date 2023-03-05 19:26:54
 */
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

template <class OP>
class LazySegmentTree {
 private:
  using T = typename decay<decltype(OP::ID)>::type;
  using st2 = int;

  st2 sz;
  struct Node {
    T val, la = 0, ls = OP::ID2;
    // st2 ind;
    int l = -1, r = -1;
    Node() : val(OP::ID) {}
    Node(T _val) : val(_val) {}
  };
  vector<Node> data;

  void push(int ind, st2 l, st2 r) {
    if (l != r) {
      if (data[ind].l == -1) {
        data.push_back(Node());
        data[ind].l = (int)data.size() - 1;
      }
      if (data[ind].r == -1) {
        data.push_back(Node());
        data[ind].r = (int)data.size() - 1;
      }
    }
    if (data[ind].ls == OP::ID2 && data[ind].la == 0) return;
    if (data[ind].ls == OP::ID2) {
      if (data[ind].la == 0) return;
      data[ind].val += OP::all(l, r, data[ind].la);
      if (l != r) {
        data[data[ind].l].la += data[ind].la;
        data[data[ind].r].la += data[ind].la;
      }
      data[ind].la = 0;
    } else {
      data[ind].ls += data[ind].la;
      data[ind].la = 0;

      data[ind].val = OP::all(l, r, data[ind].ls);
      if (l != r) {
        data[data[ind].l].ls = data[ind].ls;
        data[data[ind].l].la = 0;
        data[data[ind].r].ls = data[ind].ls;
        data[data[ind].r].la = 0;
      }
      data[ind].ls = OP::ID2;
    }
  }
  void pull(int i) {
    data[i].val = OP::comb((data[i].l == -1) ? OP::ID : data[data[i].l].val,
                           (data[i].r == -1) ? OP::ID : data[data[i].r].val);
  }

  void modify(st2 a, st2 b, T v, bool add, int ind, st2 l, st2 r) {
    push(ind, l, r);
    if (r < a || b < l) return;
    if (a <= l && r <= b) {
      if (add)
        data[ind].la += v;
      else
        data[ind].ls = v;
      push(ind, l, r);
      return;
    }

    st2 mid = (l + r) / 2;
    modify(a, b, v, add, data[ind].l, l, mid);
    modify(a, b, v, add, data[ind].r, mid + 1, r);
    pull(ind);
  }
  T query(st2 a, st2 b, int ind, st2 l, st2 r) {
    push(ind, l, r);
    if (r < a || b < l) return OP::ID;
    if (a <= l && r <= b) return data[ind].val;

    st2 mid = (l + r) / 2;
    return OP::comb(query(a, b, data[ind].l, l, mid),
                    query(a, b, data[ind].r, mid + 1, r));
  }

 public:
  LazySegmentTree() {}
  LazySegmentTree(st2 _sz) {
    sz = 1;
    while (sz < _sz) sz *= 2;
    data.reserve(64 * 123456);
    data.push_back(Node());
  }
  LazySegmentTree(const vector<T> &arr) {
    sz = 1;
    while (sz < (st2)arr.size()) sz *= 2;

    auto build = [&](auto &self, st2 l, st2 r) -> int {
      if (l == r) {
        data.push_back(Node(arr[l]));
        return (int)data.size() - 1;
      }

      data.push_back(Node());
      int ind = (int)data.size() - 1;

      st2 mid = (l + r) / 2;
      auto tmp = self(self, l, mid);
      data[ind].l = tmp;
      if ((st2)arr.size() - 1 >= mid + 1) {
        tmp = self(self, mid + 1, r);
        data[ind].r = tmp;
      }
      pull(ind);
      return ind;
    };
    build(build, 0, sz - 1);
  }

  void set(st2 a, st2 b, T v) { modify(a, b, v, false, 0, 0, sz - 1); }
  void set(st2 i, T v) { modify(i, i, v, false, 0, 0, sz - 1); }
  void add(st2 a, st2 b, T v) { modify(a, b, v, true, 0, 0, sz - 1); }
  void add(st2 i, T v) { modify(i, i, v, true, 0, 0, sz - 1); }
  T query(st2 a, st2 b) { return query(a, b, 0, 0, sz - 1); }
};
template <class T>
struct Add {
  static constexpr T ID = 0, ID2 = -1;  // change ID2 as needed
  static T comb(T a, T b) { return a + b; }
  template <class U>
  static T all([[maybe_unused]] U l, [[maybe_unused]] U r, T v) {
    return (r - l + 1) * v;
  }
};
template <class T>
using Seg = LazySegmentTree<Add<T>>;

int main() {
  ios::sync_with_stdio(false);

#ifdef LOCAL
  // freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  freopen("log.txt", "w", stderr);
#else
  cin.tie(nullptr);
#endif

  Seg<int> seg((ll)1e9 + 1);

  int M;
  cin >> M;
  ll C = 0;
  while (M--) {
    int D;
    ll X, Y;
    cin >> D >> X >> Y;
    if (D == 1)
      cout << (C = seg.query(X + C, Y + C)) << '\n';
    else
      seg.set(X + C, Y + C, 1);
  }
}
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 0 ms 336 KB Output is correct
3 Correct 1 ms 212 KB Output is correct
4 Correct 15 ms 3924 KB Output is correct
5 Correct 21 ms 4692 KB Output is correct
6 Correct 19 ms 4564 KB Output is correct
7 Correct 25 ms 4712 KB Output is correct
8 Correct 136 ms 33516 KB Output is correct
9 Correct 291 ms 55296 KB Output is correct
10 Correct 308 ms 63472 KB Output is correct
11 Correct 299 ms 68788 KB Output is correct
12 Correct 295 ms 71092 KB Output is correct
13 Correct 273 ms 87276 KB Output is correct
14 Correct 285 ms 88132 KB Output is correct
15 Runtime error 432 ms 262144 KB Execution killed with signal 9
16 Halted 0 ms 0 KB -