제출 #1352042

#제출 시각아이디문제언어결과실행 시간메모리
1352042avighnaFish 2 (JOI22_fish2)C++20
13 / 100
4094 ms13992 KiB
#include <bits/stdc++.h>

using namespace std;

const int64_t inf = 1e15;

// max queries, range add
class lazy_segment_tree {
  int n;
  vector<int64_t> seg, lazy;

  void push(int v) {
    seg[v] += lazy[v];
    if (v < 2 * n) {
      lazy[2 * v] += lazy[v];
      lazy[2 * v + 1] += lazy[v];
    }
    lazy[v] = 0;
  }
  void pull(int v) { seg[v] = max(seg[2 * v], seg[2 * v + 1]); }

  void add(int v, int tl, int tr, int l, int r, int64_t del) {
    push(v);
    if (r < tl || tr < l) {
      return;
    }
    if (l <= tl && tr <= r) {
      lazy[v] += del;
      push(v);
      return;
    }
    int tm = (tl + tr) / 2;
    add(2 * v, tl, tm, l, r, del);
    add(2 * v + 1, tm + 1, tr, l, r, del);
    pull(v);
  }

  template <typename Fn>
  int min_right(int v, int tl, int tr, int l, const Fn &f) {
    push(v);
    if (tr < l || !f(seg[v])) {
      return n;
    }
    if (tl == tr) {
      return tl;
    }
    int tm = (tl + tr) / 2;
    int ans = min_right(2 * v, tl, tm, l, f);
    if (ans != n) {
      return ans;
    }
    return min_right(2 * v + 1, tm + 1, tr, l, f);
  }

  template <typename Fn>
  int max_left(int v, int tl, int tr, int r, const Fn &f) {
    push(v);
    if (r < tl || !f(seg[v])) {
      return -1;
    }
    if (tl == tr) {
      return tl;
    }
    int tm = (tl + tr) / 2;
    int ans = max_left(2 * v + 1, tm + 1, tr, r, f);
    if (ans != -1) {
      return ans;
    }
    return max_left(2 * v, tl, tm, r, f);
  }

  int64_t at(int v, int tl, int tr, int i) {
    push(v);
    if (i < tl || tr < i) {
      return 0;
    }
    if (tl == tr && tl == i) {
      return seg[v];
    }
    int tm = (tl + tr) / 2;
    return at(2 * v, tl, tm, i) + at(2 * v + 1, tm + 1, tr, i);
  }

public:
  lazy_segment_tree(int n) : n(n), seg(4 * n), lazy(4 * n) {}

  void add(int l, int r, int64_t del) { add(1, 0, n - 1, l, r, del); }
  template <typename Fn>
  int min_right(int l, const Fn &f) { return min_right(1, 0, n - 1, l, f); }
  template <typename Fn>
  int max_left(int r, const Fn &f) { return max_left(1, 0, n - 1, r, f); }
  int64_t at(int64_t i) { return at(1, 0, n - 1, i); }
};

int main() {
  cin.tie(nullptr)->sync_with_stdio(false);

  int n;
  cin >> n;
  vector<int64_t> a(n);
  for (int64_t &i : a) {
    cin >> i;
  }

  auto solve = [&](int l, int r) {
    vector<int64_t> b;
    for (int i = l; i <= r; ++i) {
      b.push_back(a[i]);
    }
    const int n = b.size();
    vector<int64_t> pb(n);
    partial_sum(b.begin(), b.end(), pb.begin());

    lazy_segment_tree st(n);
    for (int64_t i = 0, sum = 0; i < n; ++i) {
      st.add(i, i, b[i] - (sum - b[0]));
      sum += b[i];
    }
    int ans = 0;
    set<int> st_fr;
    for (int i = 0; i < n; ++i) {
      st_fr.insert(i);
    }
    for (int i = 0; i < n; ++i) {
      int lef = i - 1, rig = i + 1;
      if (st_fr.contains(i)) {
        auto left_sum = [&]() { return pb[i] - (lef == -1 ? 0 : pb[lef]) - b[i]; };
        auto right_sum = [&]() { return pb[rig - 1] - pb[i]; };
        int changed = 1;
        while (changed) {
          auto _lef = lef, _rig = rig;
          changed = 0;
          if (rig != n) {
            rig = st.min_right(rig, [&](int64_t x) { return left_sum() + b[i] < x; });
          }
          if (lef != -1) {
            lef = st.max_left(lef, [&](int64_t x) { return b[i] + right_sum() < x; });
          }
          changed = _lef != lef || _rig != rig;
        }
      }
      if (lef == -1 && rig == n) {
        ans++;
      } else {
        auto f = [&](int x) { return st_fr.lower_bound(x); };
        for (auto it = f(lef + 1); it != st_fr.end() && *it < rig; it = f(lef + 1)) {
          st_fr.erase(it);
        }
      }
      // i to i+1
      if (i != n - 1) {
        st.add(i + 1, n - 1, b[i + 1]);
      }
      if (i != 0) {
        st.add(0, i - 1, -b[i]);
      }
      st.add(i, i, -st.at(i) + b[i]);
    }
    return ans;
  };

  int q;
  cin >> q;
  while (q--) {
    int t;
    cin >> t;
    if (t == 1) {
      int x, y;
      cin >> x >> y;
      a[x - 1] = y;
    } else {
      int l, r;
      cin >> l >> r;
      cout << solve(l - 1, r - 1) << endl;
    }
  }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...