Submission #884604

#TimeUsernameProblemLanguageResultExecution timeMemory
884604MattTheNubMonkey and Apple-trees (IZhO12_apple)C++17
100 / 100
182 ms70736 KiB
#include <bits/stdc++.h> using namespace std; #include <ext/pb_ds/assoc_container.hpp> using namespace __gnu_pbds; template <class T> using v = vector<T>; using ll = long long; using dd = long double; using int2 = pair<int, int>; using ll2 = pair<ll, ll>; using dd2 = pair<dd, dd>; #define f first #define s second #define all(x) begin(x), end(x) istream &__cin = cin; #ifdef DEV_MODE #include "debug.h" __cinwrapper __cin_wrapper; #define cin __cin_wrapper #else #define dbg(...) #define dbg2d(...) #endif template <class T1, class T2> istream &operator>>(istream &in, pair<T1, T2> &p) { in >> p.first >> p.second; return in; } template <class T> istream &operator>>(istream &in, v<T> &v) { for (auto &x : v) in >> x; return in; } mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); /* _______________________________________ ( If you don't fail at least 90% of the ) ( time, you're not aiming high enough. ) ( ) ( - Alan Kay ) --------------------------------------- o ^__^ o (oo)\_______ (__)\ )\/\ ||----w | || || */ const bool INTERACTIVE = false; const bool MULTITEST = false; /******************************************************************************/ #pragma region templates namespace ops { template <class T> struct dummy { constexpr static T IDENTITY = 0; static T comb(T a, T b) { return a ^ b; } }; template <class T> struct plus { constexpr static T IDENTITY = 0; static T comb(T a, T b) { return a + b; } }; template <class T> struct times { constexpr static T IDENTITY = 1; static T comb(T a, T b) { return a * b; } }; template <class T> struct min { constexpr static T IDENTITY = std::numeric_limits<T>::max(); static T comb(T a, T b) { return std::min(a, b); } }; template <class T> struct max { constexpr static T IDENTITY = std::numeric_limits<T>::min(); static T comb(T a, T b) { return std::max(a, b); } }; }; // namespace ops namespace upd { template <class T> struct add { T data; static add IDENTITY; static add plus_eq(T val) { return {val}; } void composite(add other) { data += other.data; } void apply(T &val, int, int, ops::dummy<T>) const { val += data; } void apply(T &val, int l, int r, ops::plus<T>) const { val += data * (r - l + 1); } void apply(T &val, int, int, ops::min<T>) const { val += data; } void apply(T &val, int, int, ops::max<T>) const { val += data; } }; template <class T> add<T> add<T>::IDENTITY = {0}; template <class T> struct set { optional<T> data; static set IDENTITY; static set eq(T val) { return {val}; } void composite(set other) { if (other.data) data = other.data; } void apply(T &val, int, int, ops::dummy<T>) const { if (data) val = data.value(); } void apply(T &val, int l, int r, ops::plus<T>) const { if (data) val = data.value() * (r - l + 1); } void apply(T &val, int, int, ops::min<T>) const { if (data) val = data.value(); } void apply(T &val, int, int, ops::max<T>) const { if (data) val = data.value(); } }; template <class T> set<T> set<T>::IDENTITY = {nullopt}; template <class T> struct add_set { bool set; T data; static add_set IDENTITY; static add_set plus_eq(T val) { return {false, val}; } static add_set eq(T val) { return {true, val}; } void composite(add_set other) { if (other.set) { data = other.data; set = true; } else { data += other.data; } } void apply(T &val, int, int, ops::dummy<T>) const { if (set) { val = data; } else { val += data; } } void apply(T &val, int l, int r, ops::plus<T>) const { if (set) { val = data * (r - l + 1); } else { val += data * (r - l + 1); } } void apply(T &val, int, int, ops::min<T>) const { if (set) { val = data; } else { val += data; } } void apply(T &val, int, int, ops::max<T>) const { if (set) { val = data; } else { val += data; } } }; template <class T> add_set<T> add_set<T>::IDENTITY = {false, 0}; }; // namespace upd template <class T, class Op> class seg { int n; v<T> data; void pull(int p) { data[p] = Op::comb(data[2 * p], data[2 * p + 1]); } class leaf_reference { seg &par; int p; bool mutated = 0; public: leaf_reference(seg &par, int p) : par(par), p(p + par.n) {} operator T const &() const { return par.data[p]; } operator T &() { mutated = 1; return par.data[p]; } T &operator=(T val) { mutated = 1; return par.data[p] = val; } ~leaf_reference() { if (mutated) { for (p >>= 1; p; p >>= 1) par.pull(p); } } }; public: seg(int n) : n(n), data(2 * n) { fill(all(data), Op::IDENTITY); } seg() : seg(0) {} seg(v<T> const &vals) : n(vals.size()), data(2 * n) { copy(vals.begin(), vals.end(), data.begin() + n); for (int p = n - 1; p; p--) pull(p); } seg(seg const &copy) : n(copy.n) { data = new T[2 * n]; std::copy(copy.data, copy.data + 2 * n, data); } int size() const { return n; } T comb(T l, T r) const { return Op::comb(l, r); } T operator()(int l, int r) const { #ifdef DEV_MODE assert(l >= 0); assert(r < n); assert(l <= r); #endif T ra = Op::IDENTITY, rb = Op::IDENTITY; for (l += n, r += n + 1; l < r; l >>= 1, r >>= 1) { if (l & 1) ra = Op::comb(ra, data[l++]); if (r & 1) rb = Op::comb(data[--r], rb); } return Op::comb(ra, rb); } leaf_reference operator[](int p) { #ifdef DEV_MODE assert(p >= 0 && p < n); #endif return leaf_reference(*this, p); } T const &operator[](int p) const { #ifdef DEV_MODE assert(p >= 0 && p < n); #endif return data[p + n]; } }; #define DEV_MODE_LAZY_SUPPORT template <class T, class Op, class Upd> class lazy { int n; v<T> data; v<Upd> upds; void pull(int p) { data[p] = Op::comb(data[2 * p], data[2 * p + 1]); } void push(int p, int l, int mid, int r) { upds[p].apply(data[2 * p], l, mid, Op()); upds[p].apply(data[2 * p + 1], mid + 1, r, Op()); upds[2 * p].composite(upds[p]); upds[2 * p + 1].composite(upds[p]); upds[p] = Upd::IDENTITY; } T qry(int p, int l, int r, int a, int b) { if (a > r || b < l) return Op::IDENTITY; if (a <= l && r <= b) return data[p]; int mid = (l + r) >> 1; push(p, l, mid, r); return Op::comb(qry(2 * p, l, mid, a, b), qry(2 * p + 1, mid + 1, r, a, b)); } void upd(int p, int l, int r, int a, int b, Upd const &u) { if (a > r || b < l) return; if (a <= l && r <= b) { u.apply(data[p], l, r, Op()); upds[p].composite(u); return; } int mid = (l + r) >> 1; push(p, l, mid, r); upd(2 * p, l, mid, a, b, u); upd(2 * p + 1, mid + 1, r, a, b, u); pull(p); } class range_reference { int l, r; lazy &par; public: range_reference(int l, int r, lazy &par) : l(l), r(r), par(par) {} operator T() { return par.qry(1, 0, par.n - 1, l, r); } void operator+=(T val) { par.upd(1, 0, par.n - 1, l, r, Upd::plus_eq(val)); } void operator-=(T val) { par.upd(1, 0, par.n - 1, l, r, Upd::plus_eq(-val)); } void operator=(T val) { par.upd(1, 0, par.n - 1, l, r, Upd::eq(val)); } }; class leaf_reference { int p; bool mutated; lazy &par; public: leaf_reference(lazy &par, int p) : p(p), par(par) {} ~leaf_reference() { if (mutated) { int l = 0, r = par.n - 1, i = 1; while (l < r) { int mid = (l + r) >> 1; i <<= 1; par.push(p, l, mid, r); if (mid >= p) { r = mid; } else { l = mid + 1; i++; } } p += par.n; for (p >>= 1; p; p >>= 1) par.pull(p); } } operator T const &() const { par.qry(1, 0, par.n - 1, p, p); return par.data[p + par.n]; } operator T &() { par.qry(1, 0, par.n - 1, p, p); mutated = 1; return par.data[p + par.n]; } T &operator=(T val) { mutated = 1; return par.data[p + par.n] = val; } }; public: lazy(int n) : n(1 << (32 - __builtin_clz(max(1, n - 1)))), data(2 * this->n), upds(2 * this->n) { fill(data.begin(), data.end(), Op::IDENTITY); fill(upds.begin(), upds.end(), Upd::IDENTITY); } lazy() : lazy(0) {} lazy(v<T> const &vals) : n(1 << (32 - __builtin_clz(max(1, (int)vals.size() - 1)))), data(2 * this->n), upds(2 * this->n) { copy(vals.begin(), vals.end(), data.begin() + n); fill(data.begin() + n + vals.size(), data.end(), Op::IDENTITY); fill(upds.begin(), upds.begin() + 2 * n, Upd::IDENTITY); for (int p = n - 1; p; p--) pull(p); } int size() const { return n; } T comb(T l, T r) const { return Op::comb(l, r); } range_reference operator()(int l, int r) { #ifdef DEV_MODE assert(l >= 0); assert(r < n); assert(l <= r); #endif return range_reference(l, r, *this); } leaf_reference operator[](int p) { #ifdef DEV_MODE assert(p >= 0 && p < n); #endif return leaf_reference(*this, p); } }; #define DEV_MODE_SPARSE_SUPPORT template <class T, class Op, class Upd> class sparse { struct node { T data = Op::IDENTITY; Upd upd = Upd::IDENTITY; int ch = -1; }; ll l, r; v<node> tree; void pull(int p) { tree[p].data = Op::comb(tree[tree[p].ch].data, tree[tree[p].ch + 1].data); } void push(int p, ll l, ll mid, ll r) { if (tree[p].ch == -1) { tree[p].ch = tree.size(); tree.emplace_back(); tree.emplace_back(); } tree[p].upd.apply(tree[tree[p].ch].data, l, mid, Op()); tree[p].upd.apply(tree[tree[p].ch + 1].data, mid + 1, r, Op()); tree[tree[p].ch].upd.composite(tree[p].upd); tree[tree[p].ch + 1].upd.composite(tree[p].upd); tree[p].upd = Upd::IDENTITY; } T qry(int p, ll l, ll r, ll a, ll b) { if (a > r || b < l) return Op::IDENTITY; if (a <= l && r <= b) return tree[p].data; ll mid = l + ((r - l) >> 1); push(p, l, mid, r); return Op::comb(qry(tree[p].ch, l, mid, a, b), qry(tree[p].ch + 1, mid + 1, r, a, b)); } void upd(int p, ll l, ll r, ll a, ll b, Upd const &u) { if (a > r || b < l) return; if (a <= l && r <= b) { u.apply(tree[p].data, l, r, Op()); tree[p].upd.composite(u); return; } ll mid = l + ((r - l) >> 1); push(p, l, mid, r); upd(tree[p].ch, l, mid, a, b, u); upd(tree[p].ch + 1, mid + 1, r, a, b, u); pull(p); } node &get_node(ll p) { int i = 0; ll l = this->l, r = this->r; while (l < r) { ll mid = l + ((r - l) >> 1); push(i, l, mid, r); if (p <= mid) { r = mid; i = tree[i].ch; } else { l = mid + 1; i = tree[i].ch + 1; } } return tree[i]; } void pull_node(ll i, int p, ll l, ll r) { if (l < r) { ll mid = l + ((r - l) >> 1); push(p, l, mid, r); if (i <= mid) { pull_node(i, tree[p].ch, l, mid); } else { pull_node(i, tree[p].ch + 1, mid + 1, r); } pull(p); } } void pull_node(ll i) { pull_node(i, 0, l, r); } class range_reference { ll l, r; sparse &par; public: range_reference(ll l, ll r, sparse &par) : l(l), r(r), par(par) {} operator T() { return par.qry(0, par.l, par.r, l, r); } void operator+=(T val) { par.upd(0, par.l, par.r, l, r, Upd::plus_eq(val)); } void operator-=(T val) { par.upd(0, par.l, par.r, l, r, Upd::plus_eq(-val)); } void operator=(T val) { par.upd(0, par.l, par.r, l, r, Upd::eq(val)); } }; class leaf_reference { ll p; bool mutated; sparse &par; public: leaf_reference(sparse &par, ll p) : p(p), par(par) {} ~leaf_reference() { if (mutated) { par.pull_node(p); } } operator T const &() const { return par.get_node(p).data; } operator T &() { mutated = 1; return par.get_node(p).data; } T &operator=(T val) { mutated = 1; return par.get_node(p).data = val; } }; public: sparse(ll l, ll r) : l(l), r(r) { tree.push_back({Op::IDENTITY, Upd::IDENTITY, -1}); } sparse() : sparse(0) {} ll size() const { return r - l + 1; } ll left() const { return l; } ll right() const { return r; } // reserve capacity for `size` nodes // set size = 2 * Q * log(N) void reserve(size_t size) { tree.reserve(size); } range_reference operator()(ll l, ll r) { #ifdef DEV_MODE assert(l >= this->l); assert(r <= this->r); assert(l <= r); #endif return range_reference(l, r, *this); } leaf_reference operator[](ll p) { #ifdef DEV_MODE assert(p >= this->l && p <= this->r); #endif return leaf_reference(*this, p); } }; #pragma endregion templates void solve() { int m; cin >> m; sparse<int, ops::plus<int>, upd::set<int>> seg(1, 1e9); seg.reserve(6000000); int c = 0; while (m--) { int d, x, y; cin >> d >> x >> y; x += c; y += c; if (d == 1) { cout << (c = seg(x, y)) << '\n'; } else { seg(x, y) = 1; } } } int main() { #ifdef DEV_MODE debug_start(INTERACTIVE, "misc-in.txt"); #else ios::sync_with_stdio(false); cin.tie(nullptr); #endif int t; if (MULTITEST) cin >> t; else t = 1; while (t--) solve(); #ifdef DEV_MODE debug_exit(INTERACTIVE); #endif } #ifdef DEV_MODE #include "debug.cpp" #endif

Compilation message (stderr)

apple.cpp:57: warning: ignoring '#pragma region templates' [-Wunknown-pragmas]
   57 | #pragma region templates
      | 
apple.cpp:543: warning: ignoring '#pragma endregion templates' [-Wunknown-pragmas]
  543 | #pragma endregion templates
      |
#Verdict Execution timeMemoryGrader output
Fetching results...