Submission #1352034

#TimeUsernameProblemLanguageResultExecution timeMemory
1352034avighnaFish 2 (JOI22_fish2)C++20
13 / 100
4094 ms16348 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];
    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(8 * 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;
    for (int i = 0; i < n; ++i) {
      int lef = i - 1, rig = i + 1;
      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;
      }
      ans += lef == -1 && rig == n;
      // 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...