제출 #1129817

#제출 시각아이디문제언어결과실행 시간메모리
1129817crafticatEscape Route 2 (JOI24_escape2)C++20
0 / 100
3094 ms6048 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;

ll sign(ll x) {
    if (x >= 0) return 1;
    return -1;
}

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> &in, bool sign) {
    V<pair<pi, ll>> results;
    for (auto [dat, c] : current) {
        auto [a,b] = dat;
        auto it = std::lower_bound(in.begin(), in.end(), make_pair(b, -INF));
        if (it != in.end())
            results.emplace_back(make_pair(a, it->second), c);
        else if (!in.empty()){
            it = in.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) 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) {
        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);
            out[i].emplace_back(b, a);
        }
        sort(all(in[i]));
        sort(all(out[i]));
        out[i] = fix(out[i]);
        F0R(j, m) out[i][j].f *= -1; // Switch signs
        F0R(j, m) out[i][j].s *= -1; // Switch signs
        sort(all(out[i]));

        in[i] = fix(in[i]);
    }

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

    F0R(quer, q) {
        ll l, r; cin >> l >> r;
        l--;
        r--;

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

        ll best = INF;
        for (auto [dat, v] : times) {
            auto [x,y] = dat;
            best = min(best, y - x + v * T);
        }
        cout << best << "\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...