Submission #1267375

#TimeUsernameProblemLanguageResultExecution timeMemory
1267375LucaLucaMTwo Antennas (JOI19_antennas)C++20
13 / 100
3095 ms26952 KiB
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>

using ll = long long;
#define debug(x) #x << " = " << x << '\n'

const int INF = 1e9;

struct segtree {
  struct Node {
    int maxAll; // max delta
    int maxActive; // h maxim
    int lazy; // delta max= h - lazy
    Node() : maxAll(-1), maxActive(-INF), lazy(+INF) {}
    Node(int x, int y, int z) : maxAll(x), maxActive(y), lazy(z) {}
    Node operator + (const Node &other) const {
      Node ret;
      ret.maxAll = std::max(maxAll, other.maxAll);
      ret.maxActive = std::max(maxActive, other.maxActive);
      ret.lazy = +INF;
      return ret;
    };
  };

  int n;
  std::vector<Node> aint;

  void init(int _n) {
    n = _n;
    aint.resize(4 * n + 10);
    for (int i = 0; i < 4 * n + 10; i++) {
      aint[i] = Node(-1, -INF, +INF);
    }
  }

  void push(int node, int tl, int tr) {
    aint[node].maxAll = std::max(aint[node].maxAll, aint[node].maxActive - aint[node].lazy);
    if (tl != tr) {
      aint[2 * node].lazy = std::min(aint[2 * node].lazy, aint[node].lazy);
      aint[2 * node + 1].lazy = std::min(aint[2 * node + 1].lazy, aint[node].lazy);
    }
    aint[node].lazy = +INF;
  }

  void updateH(int node, int tl, int tr, int p, int v) { // se schimba h
    push(node, tl, tr);
    if (tl == tr) {
      aint[node].maxActive = v;
    } else {
      int mid = (tl + tr) / 2;
      if (p <= mid) {
        updateH(2 * node, tl, mid, p, v);
      } else {
        updateH(2 * node + 1, mid + 1, tr, p, v);
      }
      push(2 * node, tl, mid);
      push(2 * node + 1, mid + 1, tr);
      aint[node] = aint[2 * node] + aint[2 * node + 1];
    }
  }
  void update(int node, int tl, int tr, int l, int r, int v) { // a[l] max= h[l] - v 
    push(node, tl, tr);
    if (l <= tl && tr <= r) {
      aint[node].lazy = v;
    } else {
      int mid = (tl + tr) / 2;
      if (l <= mid) {
        update(2 * node, tl, mid, l, r, v);
      } 
      if (mid < r) {
        update(2 * node + 1, mid + 1, tr, l, r, v);
      }
      push(2 * node, tl, mid);
      push(2 * node + 1, mid + 1, tr);
      aint[node] = aint[2 * node] + aint[2 * node + 1];
    }
  }
  int query(int node, int tl, int tr, int l, int r) {
    push(node, tl, tr);
    if (l <= tl && tr <= r) {
      return aint[node].maxAll;
    }
    int mid = (tl + tr) / 2;
    if (l <= mid && mid < r) {
      return std::max(query(2 * node, tl, mid, l, r), query(2 * node + 1, mid + 1, tr, l, r));
    } else if (l <= mid) {
      return query(2 * node, tl, mid, l, r);
    } else {
// aici a fost pierduta 1h VVVVV  (neaparat trebuie pus aceset +1)
      return query(2 * node + 1, mid + 1, tr, l, r);
    }
  }

  void updateH(int p, int newH) {
    updateH(1, 1, n, p + 1, newH);
  }
  void update(int l, int r, int v) {
    if (l > r) {
      return;
    }
    update(1, 1, n, l + 1, r + 1, v);
  }
  int query(int l, int r) {
    return query(1, 1, n, l + 1, r + 1);
  }
};

int main() {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(0);
  
  int n;
  std::cin >> n;

  std::vector<int> h(n), lt(n), rt(n);

  for (int i = 0; i < n; i++) {
    std::cin >> h[i] >> lt[i] >> rt[i];
  }

  int q;
  std::cin >> q;

  std::vector<std::pair<int, int>> Q(q);
  std::vector<int> answer(q, -1);
  for (auto &[l, r] : Q) {
    std::cin >> l >> r;
    l--, r--;
  }

  auto solve = [&]() {
    std::vector<int> l(n), r(n), l2(n), r2(n);
    std::vector<std::vector<int>> events(n);
    std::vector<std::vector<int>> queries(n);

    for (int i = 0; i < n; i++) {
      l[i] = lt[i] + i;
      r[i] = rt[i] + i;
      l2[i] = i - rt[i];
      r2[i] = i - lt[i];
      if (r[i] + 1 < n) {
        events[r[i] + 1].push_back(-(i + 1));
      }
      if (l[i] < n) {
        events[std::max(0, l[i])].push_back(+(i + 1));
      }
      l2[i] = std::max(l2[i], 0);
      r2[i] = std::min(r2[i], n - 1);
    }

    for (int i = 0; i < q; i++) {
      queries[Q[i].second].push_back(i);
    }

    std::vector<int> a(n, -INF);
    std::vector<int> b(n, -1);
    
    segtree DS;
    DS.init(n);

    for (int i = 0; i < n; i++) {
      std::sort(events[i].begin(), events[i].end());
      for (int j : events[i]) {
        int p = std::abs(j) - 1;
        std::vector<int> bef(n);
        for (int k = 0; k < n; k++) {
          bef[k] = DS.query(k, k);
        }
        if (j > 0) { // add
          DS.updateH(p, h[p]);
        } else { // remove
          DS.updateH(p, -INF);
        }
      }

      DS.update(l2[i], r2[i], h[i]);
      for (int j = l2[i]; j <= r2[i]; j++) {
        b[j] = std::max(b[j], a[j] - h[i]);
      }

      for (int id : queries[i]) {
        auto [l, r] = Q[id];
        int cur = -INF;
        for (int j = l; j <= r; j++) {
          cur = std::max(cur, b[j]);
        }
        cur = DS.query(l, r);
        answer[id] = std::max(answer[id], cur);
      }
    }
  };

  solve();
  
  std::reverse(h.begin(), h.end());
  std::reverse(lt.begin(), lt.end());
  std::reverse(rt.begin(), rt.end());

  for (auto &[l, r] : Q) {
    l = n - 1 - l;
    r = n - 1 - r;
    std::swap(l, r);
  }

  solve();

  for (int x : answer) {
    std::cout << x << '\n';
  }
  
  return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...