Submission #1223603

#TimeUsernameProblemLanguageResultExecution timeMemory
1223603SpyrosAliv밀림 점프 (APIO21_jumps)C++20
Compilation error
0 ms0 KiB
#include <bits/stdc++.h>
using namespace std;

const int INF = 1e9;
const int LOG = 22;
int n;
vector<int> h;
vector<int> toL, toR;
vector<vector<int>> g, revG;
vector<int> deg;
vector<int> lead;
vector<vector<int>> jump, dp, jumpR, jumpL, dpR, dpL;
vector<int> roots;

struct Node {
    int maxv = 0, idx = 0, ll = -1, rr = -1;
};

class PersistentSeg {
    private:
    int n;
    vector<Node> seg;
    int t = 1;
    Node merge(Node a, Node b, int l, int r) {
        if (a.maxv >= b.maxv) {
            return {a.maxv, a.idx, l, r};
        }
        else return {b.maxv, b.idx, l, r};
    }
    int build(int l, int r) {
        if (l == r) {
            seg.push_back({0, l, l, r});
            return t++;
        }
        else {
            int mid = (l + r) / 2;
            Node nxt = {0, l, build(l, mid), build(mid+1, r)};
            seg.push_back(nxt);
            return t++;
        }
    }
    pair<int, int> query(Node node, int start, int end, int l, int r) {
        if (start > r || end < l) return {0, 0};
        if (start >= l && end <= r) {
            return {node.idx, node.maxv};
        }
        else {
            int mid = (start + end) / 2;
            pair<int, int> canda = query(seg[node.ll], start, mid, l, r), candb = query(seg[node.rr], mid+1, end, l, r);
            if (canda.second > candb.second) return canda;
            else return candb;
        }
    }
    int update(int node, int start, int end, int idx, int v) {
        if (start == end) {
            seg.push_back({v, idx, 0, 0});
            return t++;
        }
        else {
            int mid = (start + end) / 2;
            Node nxt = seg[node];
            if (mid >= idx) {
                nxt.ll = update(seg[node].ll, start, mid, idx, v);
            }
            else nxt.rr = update(seg[node].rr, mid+1, end, idx, v);
            nxt = merge(seg[nxt.ll], seg[nxt.rr], nxt.ll, nxt.rr);
            seg.push_back(nxt);
            return t++;
        }
    }
    public:
    int init(int nn) {
        n = nn;
        //Node uh;
        //seg.assign(n*LOG, uh);
        seg.push_back({0, 0, 0, 0});
        t = 1;
        return build(1, n);
    }
    int query(int root, int l, int r) {
        return query(seg[root], 1, n, l, r).first;
    }
    int update(int root, int idx, int v) {
        return update(root, 1, n, idx, v);
    }
} segTree;

void init(int N, vector<int> H) {
    n = N;
    h = {0};
    toL.assign(n+1, 0);
    toR.assign(n+1, 0);
    for (auto x: H) h.push_back(x);
    stack<int> st;
    for (int i = 1; i <= n; i++) {
        while (!st.empty() && h[st.top()] <= h[i]) st.pop();
        if (st.empty()) toL[i] = 0;
        else toL[i] = st.top();
        st.push(i);
    }
    while (!st.empty()) st.pop();
    for (int i = n; i >= 1; i--) {
        while (!st.empty() && h[st.top()] <= h[i]) st.pop();
        if (st.empty()) toR[i] = n+1;
        else toR[i] = st.top();
        st.push(i);
    }
    lead.assign(n+1, -1);
    for (int i = 1; i <= n; i++) {
        if (toL[i] < 1 && toR[i] > n) {
            lead[i] = -1;
        }
        else {
            if (toR[i] > n) lead[i] = toL[i];
            else if (toL[i] < 1) lead[i] = toR[i];
            else {
                if (h[toL[i]] > h[toR[i]]) lead[i] = toL[i];
                else lead[i] = toR[i];
            }
        }
    }
    vector<pair<int, int>> vals;
    for (int i = 1; i <= n; i++) {
        vals.push_back({h[i], i});
    }
    sort(vals.rbegin(), vals.rend());
    jump.assign(n+1, vector<int>(LOG, -1));
    dp.assign(n+1, vector<int>(LOG, 0));
    for (auto [curr, pos]: vals) {
        jump[pos][0] = lead[pos];
        dp[pos][0] = 1;
        for (int i = 1; i < LOG; i++) {
            if (jump[pos][i-1] == -1) {
                jump[pos][i] = -1;
                dp[pos][i] = -1;
                continue;
            }
            jump[pos][i] = jump[jump[pos][i-1]][i-1];
            int prev = jump[pos][i-1];
            dp[pos][i] = dp[pos][i-1] + dp[prev][i-1];
        }
    }
    jumpL.assign(n+1, vector<int>(LOG, -1));
    dpL.assign(n+1, vector<int>(LOG, 0));
    jumpR.assign(n+1, vector<int>(LOG, -1));
    dpR.assign(n+1, vector<int>(LOG, 0));
    for (int i = n; i >= 1; i--) {
        if (toR[i] > n) continue;
        jumpR[i][0] = toR[i];
        dpR[i][0] = 1;
        for (int j = 1; j < LOG; j++) {
            if (jumpR[i][j-1] == -1) {
                jumpR[i][j] = -1;
                dpR[i][j] = -1;
                continue;
            }
            jumpR[i][j] = jumpR[jumpR[i][j-1]][j-1];
            int prevPos = jumpR[i][j-1];
            dpR[i][j] = dpR[i][j-1] + dpR[prevPos][j-1];
        }
    }
    for (int i = 1; i <= n; i++) {
        if (toL[i] < 1) continue;
        jumpL[i][0] = toL[i];
        dpL[i][0] = 1;
        for (int j = 1; j < LOG; j++) {
            if (jumpL[i][j-1] == -1) {
                jumpL[i][j] = -1;
                dpL[i][j] = -1;
                continue;
            }
            jumpL[i][j] = jumpL[jumpL[i][j-1]][j-1];
            int prevPos = jumpL[i][j-1];
            dpL[i][j] = dpL[i][j-1] + dpL[prevPos][j-1];
        }
    }
    roots.push_back(segTree.init(n));
    reverse(vals.begin(), vals.end());
    for (auto [v, idx]: vals) {
        roots.push_back(segTree.update(roots.back(), idx, v));
    }
}

int minimum_jumps(int a, int b, int c, int d) {
    a++;b++;c++;d++;
    assert(c == d);
    int start = -1;
    int lo = a, hi = b;
    int allowed = -1;
    while (lo <= hi) {
        int mid = (lo + hi) / 2;
        int mx = segTree.query(roots.back(), mid, b);
        if (h[mx] < h[d]) {
            allowed = mid;
            hi = mid-1;
        }
        else lo = mid+1;
    }
    if (allowed == -1) return -1;
    a = allowed;
    int lo = 1, hi = n;
    while (lo <= hi) {
        int mid = (lo + hi) / 2;
        int mx = segTree.query(roots[mid], a, b);
        if (mx == 0 || h[mx] < h[d]) {
            if (mx != 0) start = mx;
            lo = mid+1;
        }
        else hi = mid-1;
    }
    if (start == -1) return -1;
    a = start;
    int tot = 0;
    int curr = a;
    while (curr >= 1 && curr <= n && curr != d) {
        if (jump[curr][0] == -1 || h[jump[curr][0]] > h[d]) break;
        for (int j = LOG-1; j >= 0; j--) {
            if (jump[curr][j] == -1) continue;
            if (h[jump[curr][j]] <= h[d]) {
                tot += dp[curr][j];
                curr = jump[curr][j];
                break;
            }
        }
    }
    if (curr == d) return tot;
    // now only left, or only right
    if (curr < d) {
        while (curr != d) {
            if (jumpR[curr][0] == -1 || h[jumpR[curr][0]] > h[d]) return -1;
            for (int j = LOG-1; j >= 0; j--) {
                if (jumpR[curr][j] != -1 && h[jumpR[curr][j]] <= h[d]) {
                    tot += dpR[curr][j];
                    curr = jumpR[curr][j];
                    break;
                }
            }
        }
    }
    else {
        while (curr != d) {
            if (jumpL[curr][0] == -1 || h[jumpL[curr][0]] > h[d]) return -1;
            for (int j = LOG-1; j >= 0; j--) {
                if (jumpL[curr][j] != -1 && h[jumpL[curr][j]] <= h[d]) {
                    tot += dpL[curr][j];
                    curr = jumpL[curr][j];
                    break;
                }
            }
        }
    }
    return tot;
}

Compilation message (stderr)

jumps.cpp: In function 'int minimum_jumps(int, int, int, int)':
jumps.cpp:201:9: error: redeclaration of 'int lo'
  201 |     int lo = 1, hi = n;
      |         ^~
jumps.cpp:188:9: note: 'int lo' previously declared here
  188 |     int lo = a, hi = b;
      |         ^~
jumps.cpp:201:17: error: redeclaration of 'int hi'
  201 |     int lo = 1, hi = n;
      |                 ^~
jumps.cpp:188:17: note: 'int hi' previously declared here
  188 |     int lo = a, hi = b;
      |                 ^~