제출 #1129832

#제출 시각아이디문제언어결과실행 시간메모리
1129832crafticatEscape Route 2 (JOI24_escape2)C++20
54 / 100
3095 ms44388 KiB
#include <bits/stdc++.h>

using namespace std;
using ll  =long long;
#define F0R(i, n) for (ll i = 0; i < n;i++)
#define FOR(i,j,n) for(ll i = j;i < n;i++)
template<typename T>
using V = vector<T>;
using vi = V<ll>;
using pi = pair<ll, ll>;

#define all(x) x.begin(), x.end()
#define f first
#define s second

constexpr ll INF = 1e18;
using tup = tuple<ll, ll, ll>;

vi ans;
V<V<pi>> in, out;

V<pi> fix(V<pi> arr) {
    V<pi> fixed;
    F0R(i, arr.size()) {
        while (!fixed.empty() and fixed.back().s > arr[i].s) fixed.pop_back();
        fixed.push_back(arr[i]);
    }
    return fixed;
}

ll T;

V<pair<pi, ll>> create(V<pi> x) {
    V<pair<pi, ll>> ans(x.size());
    for (ll i = 0; i < x.size(); ++i) {
        ans[i] = {x[i], 0};
    }
    return ans;
}

V<pair<pi, ll>> next(const V<pair<pi, ll>> &current, ll i, V<pi> &next, bool sign) {
    V<pair<pi, ll>> results;
    for (auto [dat, c] : current) {
        auto [a,b] = dat;
        auto it = std::lower_bound(next.begin(), next.end(), make_pair(b, -INF));
        if (it != next.end())
            results.emplace_back(make_pair(a, it->second), c);
        else if (!next.empty()){
            it = next.begin();
            results.emplace_back(make_pair(a, it->second), c + 1);
        }
    }
    return results;
}

// Must jump over all l and r
void solve(ll l, ll r, V<tuple<ll,ll,ll>> queries) {
    ll mid = (r + l) / 2;
    if (r - l <= 1) {
        V<pair<pi, ll>> times = create(in[l]);

        for (auto [a,b, i] : queries) {
            ll res = INF;
            for (auto [dat, r] : times) {
                auto [x,y] = dat;
                res = min(res, y - x);
            }
            ans[i] = res;
        }
        return;
    }

    V<tuple<ll,ll,ll>> leftQueries, rightQueries, currentQueries;
    for (auto [a, b, i] : queries) {
        if (b <= mid) leftQueries.emplace_back(a,b,i);
        else if (a >= mid) rightQueries.emplace_back(a, b, i);
        else currentQueries.emplace_back(a, b, i);
    }

    solve(l, mid, leftQueries);
    solve(mid, r, rightQueries);

    V<pair<pi, ll>> times = create(in[mid]);
    V<V<pair<pi, ll>>> to, from;
    FOR(i, mid + 1, r) {
        to.emplace_back(times);
        times = next(times,i, in[i], false);
    }
    to.emplace_back(times);

    times = create(out[mid]);
    for (auto &[aData,r] : times) {
        auto &[a,b] = aData;
        a = -b;
    }

    for (ll i = mid - 1; i >= l;i--) {
        from.emplace_back(times);
        times = next(times, i, out[i], true);
    }
    from.emplace_back(times);

    for (auto [a,b, i] : currentQueries) {
        if (i == 0) {
            int stop = 25;
        }
        V<pair<pi, ll>> end = to[b - mid - 1];
        V<pair<pi, ll>> start = from[mid - a];

        ll bestTime = INF;
        for (auto [dat,c] : start) {
            auto [x,y] = dat;
            swap(x,y);
            x *= -1;

            for (auto [dat2, c2] : end) {
                auto [x2,y2] = dat2;
                if (y <= x2) bestTime = min(bestTime, y2 - x + (c + c2) * T);
            }
        }

        ans[i] = bestTime;
    }
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(nullptr);

    ll n; cin >> n >> T;
    in.resize(n), out.resize(n);

    F0R(i, n - 1) {
        ll m; cin >> m;
        F0R(j, m) {
            ll a, b; cin >> a >> b;
            in[i].emplace_back(a,b);
        }
        sort(all(in[i]));
        in[i] = fix(in[i]);
        for (auto [a,b] : in[i]) {
            out[i].emplace_back(b,a);
        }

        F0R(j, out[i].size()) {
            out[i][j].f *= -1; // Switch signs
            out[i][j].s *= -1; // Switch signs
        }
        sort(all(out[i]));

    }

    V<tuple<ll,ll,ll>> queries;
    ll q; cin >> q;
    ans.resize(q);

    F0R(i, q) {
        ll l, r; cin >> l >> r;
        l--;
        r--;
        queries.emplace_back(l, r, i);
    }

    solve(0, n, queries);
    F0R(i, q) {
        cout << ans[i] << "\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...