제출 #1330150

#제출 시각아이디문제언어결과실행 시간메모리
1330150M_W_13Bitaro's travel (JOI23_travel)C++20
100 / 100
167 ms55912 KiB
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define st first
#define nd second
#define pb push_back
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(a) a.begin(), a.end()
const int MAXN = 1 << 18;
const int MAXK = 32;
ll T[MAXN];
ll ans[MAXN];
ll pot[MAXK];
int lw[MAXN][MAXK];
int pr[MAXN][MAXK];

void pre(int n) {
    pot[0] = 1ll;
    for (int k = 1; k < MAXK; k++) pot[k] = pot[k - 1] * 2ll;

    rep(i, n) lw[i][0] = i-1;
    rep(i, n) pr[i][0] = i+1;

    for (int k = 1; k < MAXK; k++) {
        rep(i, n) {
            if (lw[i][k - 1] == -1) lw[i][k] = -1;
            else {
                if ((T[i] - T[lw[i][k - 1]]) >= pot[k]) lw[i][k] = lw[i][k - 1];
                else {
                    lw[i][k] = lw[lw[i][k - 1]][k - 1];
                }
            }
        }
    }

    for (int k = 1; k < MAXK; k++) {
        rep(i, n) {
            if (pr[i][k - 1] == n) pr[i][k] = n;
            else {
                if ((T[pr[i][k - 1]] - T[i]) >= pot[k]) pr[i][k] = pr[i][k - 1];
                else {
                    pr[i][k] = pr[pr[i][k - 1]][k - 1];
                }
            }
        }
    }

}

void licz(int n) {
    if (n == 1) return ;
    
    rep(i, n) {
        int l = i;
        int r = i;
        ans[i] = 0ll;
        bool t = 0;
        if (l == 0) {
            ans[i] += (T[r + 1] - T[r]);
            r++;
            t = 1;
        }
        else if (r == (n - 1)) {
            ans[i] += (T[l] - T[l - 1]);
            l--;
            t = 0;
        }
        else {
            if ((T[l] - T[l - 1]) <= (T[r + 1] - T[r])) {
                ans[i] += (T[l] - T[l - 1]);
                l--;
                t = 0;
            }
            else {
                ans[i] += (T[r + 1] - T[r]);
                r++;
                t = 1;
            }
        }
        int x = l;
        if (t) x = r;
        int k = 0;
        while ((r - l + 1) < n) {
            // cout << l << " " << r << " val = " << ans[i] << '\n';
            if (t && ((r == n - 1) || ((l > 0) && ((T[r + 1] - T[x]) >= (T[x] - T[l - 1]))))) {
                t = 0;
                ans[i] += (T[x] - T[l - 1]);
                l--;
                x = l;
                continue;
            }
            else if (t) {
                ans[i] += (T[r + 1] - T[x]);
                r++;
                x++;
            }
            if ((t == 0) && ((l == 0) || ((r < (n - 1)) && ((T[x] - T[l - 1]) > (T[r + 1] - T[x]))))) {
                t = 1;
                ans[i] += (T[r + 1] - T[x]);
                r++;
                x = r;
                continue;
            }
            else if (t == 0) {
                ans[i] += (T[x] - T[l - 1]);
                x--;
                l--;
            }
            if (t) {
                int y = pr[l][k];
                if (y <= r) {
                    k++;
                    continue;
                }
                ans[i] += (T[y - 1] - T[x]);
                r = y - 1;
                x = y - 1;
                k++;
            }
            else {
                int y = lw[r][k];
                if (y >= l) {
                    k++;
                    continue;
                }
                ans[i] += (T[x] - T[y + 1]);
                l = y + 1;
                x = y + 1;
                k++;
            }
        }
        // cout << "i = " << i << " ans = " << ans[i] << '\n';
    }

}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n;
    cin >> n;
    rep(i, n) cin >> T[i];
    pre(n);
    licz(n);
    int q;
    cin >> q;
    while (q--) {
        ll x;
        cin >> x;
        int poc = 0;
        int kon = n;
        int odp = n;
        while (poc < kon) {
            int sr = (poc + kon)/2;
            if (T[sr] >= x) {
                odp = sr;
                kon = sr;
            }
            else {
                poc = sr + 1;
            }
        }
        if (odp == 0) {
            cout << (ans[0] + T[0] - x) << '\n';
        }
        else if (odp == n) {
            cout << (ans[n - 1] + x - T[n - 1]) << '\n';
        }
        else {
            ll A = x - T[odp - 1];
            ll B = T[odp] - x;
            if (A <= B) {
                cout << (ans[odp - 1] + A) << '\n';
            }
            else {
                cout << (ans[odp] + B) << '\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...