답안 #168085

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
168085 2019-12-11T09:54:37 Z AlexPop28 3단 점프 (JOI19_jumps) C++11
0 / 100
4000 ms 34900 KB
#include <bits/stdc++.h>
#define dbg() cerr <<
#define name(x) (#x) << ": " << (x) << ' ' <<

using namespace std;

struct SegmTree {
  struct Node {
    int maxv, val, lazy;
    Node(int maxv_ = 0, int val_ = 0, int lazy_ = 0) :
      maxv(maxv_), val(val_), lazy(lazy_) {}
    // maxv = val max on [l, r] in v
    // val = maximum val of jumps in [l, r]
    // lazy = max val to update children with
  };
  int n;
  vector<int> v;
  vector<Node> tree;
  SegmTree(const vector<int> v_) : n(v_.size()), v(v_), tree(4 * n) {
    Build(0, 0, n - 1);
  }
  void Recalc(int node) {
    tree[node].val = max(tree[2 * node + 1].val, tree[2 * node + 2].val);
  }
  void Build(int node, int left, int right) {
    if (left == right) {
      tree[node].maxv = v[left];
      tree[node].val = v[left];
      tree[node].lazy = 0;
      return;
    }
    int mid = left + (right - left) / 2;
    Build(2 * node + 1, left, mid);
    Build(2 * node + 2, mid + 1, right);
    Recalc(node);
  }
  void Propagate(int node, int len) {
    if (len == 1) return;
    for (int son : {2 * node + 1, 2 * node + 2}) {
      tree[son].lazy = max(tree[son].lazy, tree[node].lazy);
      tree[son].val = max(tree[son].val, tree[son].maxv + tree[son].lazy); 
    }
  }
  void Update(int node, int left, int right, int x, int y, int val) {
    Propagate(node, right - left + 1);
    if (x <= left && right <= y) {
      tree[node].val = max(tree[node].val, tree[node].maxv + val);
      tree[node].lazy = max(tree[node].lazy, val);
      return;
    }
    int mid = left + (right - left) / 2;
    if (x <= mid)
      Update(2 * node + 1, left, mid, x, y, val);
    if (mid < y)
      Update(2 * node + 2, mid + 1, right, x, y, val);
    Recalc(node);
  }
  int Query(int node, int left, int right, int x, int y) {
    Propagate(node, right - left + 1);
    if (x <= left && right <= y) {
      return tree[node].val;
    }
    int mid = left + (right - left) / 2;
    int ret = 0;
    if (x <= mid)
      ret = max(ret, Query(2 * node + 1, left, mid, x, y));
    if (mid < y)
      ret = max(ret, Query(2 * node + 2, mid + 1, right, x, y));
    Recalc(node);
    return ret;
  }
  void Update(int l, int r, int val) {
    if (l > r) return;
    dbg() "U: " << name(l) name(r) name(val) endl;
    Update(0, 0, n - 1, l, r, val);
  }
  int Query(int l, int r) {
    dbg() "Q: " << name(l) name(r) endl;
    return Query(0, 0, n - 1, l, r);
  }
};

vector<vector<int>> GetAdd(const vector<int> &v) {
  int n = v.size();
  vector<int> stk = {-1}, lft(n), rgt(n);
  for (int i = 0; i < n; ++i) {
    while (stk.size() > 1 && v[stk.back()] < v[i]) {
      rgt[stk.back()] = i;
      stk.pop_back();
    }
    lft[i] = stk.back();
    stk.emplace_back(i);
  }
  while (!stk.empty()) {
    rgt[stk.back()] = n;
    stk.pop_back();
  }
  vector<vector<int>> to_add(n);
  for (int i = 0; i < n; ++i) {
    if (lft[i] != -1) {
      to_add[lft[i]].emplace_back(i);
    }
    if (rgt[i] != n) {
      to_add[i].emplace_back(rgt[i]);
    }
  }
  return to_add;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0), cout.tie(0);

  int n; cin >> n;
  vector<int> v(n);
  for (int &x : v) {
    cin >> x;
  }

  int q; cin >> q;
  vector<vector<pair<int, int>>> qrs(n);
  for (int i = 0; i < q; ++i) {
    int l, r; cin >> l >> r; --l, --r;
    qrs[l].emplace_back(r, i);
  }

  auto to_add = GetAdd(v);
  SegmTree tree(v);
  vector<int> ans(q);
  for (int l = n - 1; l >= 0; --l) {
    for (int &x : to_add[l]) {
      tree.Update(x + x - l, n - 1, v[l] + v[x]);
    }
    for (auto &p : qrs[l]) {
      ans[p.second] = tree.Query(l, p.first); 
    }
  }
  for (int &x : ans) {
    cout << x << '\n';
  }
}
# 결과 실행 시간 메모리 Grader output
1 Runtime error 5 ms 888 KB Execution killed with signal 11 (could be triggered by violating memory limits)
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 5 ms 888 KB Execution killed with signal 11 (could be triggered by violating memory limits)
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 4027 ms 34900 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 5 ms 888 KB Execution killed with signal 11 (could be triggered by violating memory limits)
2 Halted 0 ms 0 KB -