Submission #1352135

#TimeUsernameProblemLanguageResultExecution timeMemory
1352135gayMarathon Race 2 (JOI24_ho_t3)C++20
100 / 100
245 ms18772 KiB
#include <bits/stdc++.h>
#include <experimental/random>
#include <random>

//#include <ext/pb_ds/assoc_container.hpp>
//using namespace __gnu_pbds;

using namespace std;

using ld = long double;
using ll = long long;

const ll INF = 1e18, MOD = 1e9 + 7;

void solve();

signed main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    int q = 1;
    //cin >> q;
    while (q--) {
        solve();
    }
}

void solve() {
    ll n, l;
    cin >> n >> l;
    vector<ll> cnt(l + 1);
    vector<ll> cord;
    ll mn = INF, mx = -INF;
    for (int i = 0; i < n; i++) {
        ll x;
        cin >> x;
        cnt[x]++;
        cord.push_back(x);
        mn = min(mn, x), mx = max(mx, x);
    }
    vector<ll> pref = {0};
    for (auto c: cnt) {
        pref.push_back(pref.back() + c);
    }

    sort(cord.begin(), cord.end());
    cord.resize(unique(cord.begin(), cord.end()) - cord.begin());
    ll m = (int) cord.size();

    unordered_map<ll, vector<ll>> dp1, dp2;
    dp1[0] = {0, INF};
    dp2[0] = {INF, 0};
    for (ll len = m - 1; len > 0; len--) {
        unordered_map<ll, vector<ll>> dp1n, dp2n;
        for (auto &[i, arr]: dp1) {
            if (i + len >= m) continue;
            ll j = i + len;
            ll col = n - pref[cord[j] + 1] + pref[cord[i]] + 1;
            ll fir = min(dp1[i][0] + (col + cnt[cord[i]]) * (cord[i + 1] - cord[i]),
                         dp1[i][1] + (cord[j] - cord[i]) * col + (col + cnt[cord[i]]) * (cord[i + 1] - cord[i]));
            ll sec = min(dp1[i][0] + (cord[j] - cord[i]) * col + (col + cnt[cord[j]]) * (cord[j] - cord[j - 1]),
                         dp1[i][1] + (col + cnt[cord[j]]) * (cord[j] - cord[j - 1]));

            if (fir <= 5e5) {
                if (dp1n.find(i + 1) == dp1n.end()) {
                    dp1n[i + 1] = {INF, INF};
                }
                dp1n[i + 1][0] = min(dp1n[i + 1][0], fir);
            }
            if (sec <= 5e5) {
                if (dp1n.find(i) == dp1n.end()) {
                    dp1n[i] = {INF, INF};
                }
                dp1n[i][1] = min(dp1n[i][1], sec);
            }
        }

        for (auto &[i, arr]: dp2) {
            if (i + len >= m) continue;
            ll j = i + len;
            ll col = n - pref[cord[j] + 1] + pref[cord[i]] + 1;
            ll fir = min(dp2[i][0] + (col + cnt[cord[i]]) * (cord[i + 1] - cord[i]),
                         dp2[i][1] + (cord[j] - cord[i]) * col + (col + cnt[cord[i]]) * (cord[i + 1] - cord[i]));
            ll sec = min(dp2[i][0] + (cord[j] - cord[i]) * col + (col + cnt[cord[j]]) * (cord[j] - cord[j - 1]),
                         dp2[i][1] + (col + cnt[cord[j]]) * (cord[j] - cord[j - 1]));

            if (fir <= 5e5) {
                if (dp2n.find(i + 1) == dp2n.end()) {
                    dp2n[i + 1] = {INF, INF};
                }
                dp2n[i + 1][0] = min(dp2n[i + 1][0], fir);
            }
            if (sec <= 5e5) {
                if (dp2n.find(i) == dp2n.end()) {
                    dp2n[i] = {INF, INF};
                }
                dp2n[i][1] = min(dp2n[i][1], sec);
            }
        }

        dp1 = dp1n;
        dp2 = dp2n;
    }
    vector<ll> d1(m, INF), d2(m, INF);
    for (int i = 0; i < m; i++) {
        if (dp1.find(i) != dp1.end()) {
            d1[i] = min(dp1[i][0], dp1[i][1]);
        }
        if (dp2.find(i) != dp2.end()) {
            d2[i] = min(dp2[i][0], dp2[i][1]);
        }
    }

    ll q;
    cin >> q;
    while (q--) {
        ll s, g, t;
        cin >> s >> g >> t;
        t -= n;
        ll x = lower_bound(cord.begin(), cord.end(), g) - cord.begin();
        ll ans = INF;
        if (x < m) {
            ans = min(ans, abs(s - mn) + min(d1[x], d1[x]) + abs(cord[x] - g) * (n + 1));
            ans = min(ans, abs(s - mx) + min(d2[x], d2[x]) + abs(cord[x] - g) * (n + 1));
        }
        x--;
        if (x >= 0) {
            ans = min(ans, abs(s - mn) + min(d1[x], d1[x]) + abs(cord[x] - g) * (n + 1));
            ans = min(ans, abs(s - mx) + min(d2[x], d2[x]) + abs(cord[x] - g) * (n + 1));
        }
        if (ans <= t) {
            cout << "Yes\n";
        } else {
            cout << "No\n";
        }
    }
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...