Submission #1020204

#TimeUsernameProblemLanguageResultExecution timeMemory
1020204toast12Fountain (eJOI20_fountain)C++14
100 / 100
315 ms30392 KiB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;

vector<vector<int>> jump;
vector<vector<ll>> weight;

ll find(int u, int k) {
    int v = u;
    ll res = 0;
    for (int e = 0; e <= 20; e++) {
        if (k & (1 << e)) {
            res += weight[e][v];
            v = jump[e][v];
        }
    }
    return res;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    int n, q;
    cin >> n >> q;
    vector<int> d(n+1), c(n+1);
    c[0] = 1e9;
    for (int i = 1; i <= n; i++) {
        cin >> d[i] >> c[i];
    } 
    // d, c, i
    stack<int> s;
    vector<int> next(n+1);
    for (int i = 1; i <= n; i++) {
        while (!s.empty() && d[i] > d[s.top()]) {
            next[s.top()] = i;
            s.pop();
        }
        s.push(i);
    }
    jump.resize(20, vector<int>(n+1, -1));
    for (int i = 1; i <= n; i++) {
        jump[0][i] = next[i];
    }
    for (int e = 1; e < 20; e++) {
        for (int i = 1; i <= n; i++) {
            if (jump[e-1][i] != -1)
                jump[e][i] = jump[e-1][jump[e-1][i]];
        }
    }
    weight.resize(20, vector<ll>(n+1));
    for (int i = 1; i <= n; i++) {
        weight[0][i] = c[next[i]];
    }
    for (int e = 1; e < 20; e++) {
        for (int i = 1; i <= n; i++) {
            weight[e][i] = weight[e-1][i];
            if (jump[e-1][i] != -1)
                weight[e][i] += weight[e-1][jump[e-1][i]];
        }
    }
    while (q--) {
        int r, v;
        cin >> r >> v;
        if (v <= c[r]) {
            cout << r << '\n';
            continue;
        }
        v -= c[r];
        int lo = 0, hi = 0;
        for (int e = 0; e < 20; e++) {
            if (weight[e][r] >= v) {
                lo = 1 << (e-1);
                hi = 1 << e;
                break;
            }
        }
        while (lo < hi) {
            int mid = (lo+hi)/2;
            ll x = find(r, mid);
            if (x >= v) {
                hi = mid;
            }
            else {
                lo = mid+1;
            }
        }
        int u = r;
        for (int e = 0; e < 20; e++) {
            if (hi & (1 << e))
                u = jump[e][u];
        }
        cout << u << '\n';
    }
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...