제출 #706135

#제출 시각아이디문제언어결과실행 시간메모리
706135nhuang685원숭이와 사과 나무 (IZhO12_apple)C++17
0 / 100
491 ms262144 KiB
/**
 * @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 = long long;

  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 (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) {
      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.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<ll> 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);
  }
}
#Verdict Execution timeMemoryGrader output
Fetching results...