Submission #1011275

#TimeUsernameProblemLanguageResultExecution timeMemory
1011275victor_gaoMarathon Race 2 (JOI24_ho_t3)C++17
100 / 100
777 ms137196 KiB
//#pragma GCC optimize("Ofast,unroll-loops,O3")
//#pragma GCC target("avx,avx2,sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,fma,tune=native")
#include <bits/stdc++.h>
#define int long long
#define pii pair<int, int>
#define x first
#define y second
#define N 2015
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int n, m, L, s[N], arr[500015], dpl[N][N][2], dpr[N][N][2];
vector<int> all;
struct segtree{
    int seg[4 * N], tag[4 * N];
    void push(int i){
        if (tag[i]){
            tag[2 * i] += tag[i];
            tag[2 * i + 1] += tag[i];
            seg[2 * i] += tag[i];
            seg[2 * i + 1] += tag[i];
            tag[i] = 0;
        }
    }
    void modify(int l, int r, int i, int ll, int rr, int c){
        if (ll > rr) return;
        if (ll <= l && rr >= r){
            tag[i] += c, seg[i] += c;
            return;
        }
        int mid = (l + r) >> 1; push(i);
        if (ll <= mid) modify(l, mid, 2 * i, ll, rr, c);
        if (rr > mid) modify(mid + 1, r, 2 * i + 1, ll, rr, c);
        seg[i] = min(seg[2 * i], seg[2 * i + 1]);
    }
    int query(int l, int r, int i, int ll, int rr){
        if (ll > rr) return 5e18;
        if (ll <= l && rr >= r)
            return seg[i];
        int mid = (l + r) >> 1; push(i);
        if (rr <= mid) return query(l, mid, 2 * i, ll, rr);
        else if (ll > mid) return query(mid + 1, r, 2 * i + 1, ll, rr);
        else return min(query(l, mid, 2 * i, ll, rr), query(mid + 1, r, 2 * i + 1, ll, rr));
    }
}l1, l2, r1, r2;

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> L;
    for (int i = 1; i <= n; i++)
        cin >> arr[i], all.push_back(arr[i]);
    sort(all.begin(), all.end());
    all.resize(unique(all.begin(), all.end()) - all.begin());
    m = all.size();
    if (m <= 2000){
        sort(arr + 1, arr + 1 + n);
        for (int i = 1; i <= n; i++){
            int p = upper_bound(all.begin(), all.end(), arr[i]) - all.begin();
            s[p]++;
        }
        unique(arr + 1, arr + 1 + n);
        for (int i = 1; i <= m; i++)
            s[i] += s[i - 1];

        for (int i = 0; i <= m + 1; i++)
            for (int j = 0; j <= m + 1; j++){
                dpl[i][j][0] = dpl[i][j][1] = 5e15;
                dpr[i][j][0] = dpr[i][j][1] = 5e15;
            }
        dpl[1][m][0] = 0, dpl[1][m][1] = arr[m] - arr[1];
        dpr[1][m][0] = arr[m] - arr[1], dpr[1][m][1] = 0;

        for (int j = m - 1; j >= 1; j--){
            for (int i = 1; i <= m - j + 1; i++){
                dpl[i][j][0] = dpl[i - 1][j + 1][0] + (arr[i] - arr[i - 1]) * (n - (s[i + j - 1] - s[i - 1]) + 1);
                dpl[i][j][1] = dpl[i][j + 1][1] + (arr[i + j] - arr[i + j - 1]) * (n - (s[i + j - 1] - s[i - 1]) + 1);
                dpl[i][j][0] = min({(int)5e15, dpl[i][j][0], dpl[i][j][1] + (arr[i + j - 1] - arr[i]) * (n - (s[i + j - 1] - s[i - 1]) + 1)});
                dpl[i][j][1] = min({(int)5e15, dpl[i][j][1], dpl[i][j][0] + (arr[i + j - 1] - arr[i]) * (n - (s[i + j - 1] - s[i - 1]) + 1)});

                dpr[i][j][0] = dpr[i - 1][j + 1][0] + (arr[i] - arr[i - 1]) * (n - (s[i + j - 1] - s[i - 1]) + 1);
                dpr[i][j][1] = dpr[i][j + 1][1] + (arr[i + j] - arr[i + j - 1]) * (n - (s[i + j - 1] - s[i - 1]) + 1);
                dpr[i][j][0] = min({(int)5e15, dpr[i][j][0], dpr[i][j][1] + (arr[i + j - 1] - arr[i]) * (n - (s[i + j - 1] - s[i - 1]) + 1)});
                dpr[i][j][1] = min({(int)5e15, dpr[i][j][1], dpr[i][j][0] + (arr[i + j - 1] - arr[i]) * (n - (s[i + j - 1] - s[i - 1]) + 1)});
            }
        }

        for (int i = 1; i <= m; i++){
            l1.modify(1, m, 1, i, i, dpl[i][1][0] - arr[i] * (n + 1));
            l2.modify(1, m, 1, i, i, dpl[i][1][0] + arr[i] * (n + 1));
            r1.modify(1, m, 1, i, i, dpr[i][1][0] - arr[i] * (n + 1));
            r2.modify(1, m, 1, i, i, dpr[i][1][0] + arr[i] * (n + 1));
        }
    }
    int q; cin >> q;
    while (q--){
        int S, t, T;
        cin >> S >> t >> T;
        if (m <= 2000){
            int p = upper_bound(arr + 1, arr + 1 + m, t) - arr;
            l1.modify(1, m, 1, 1, p - 1, t * (n + 1));
            l2.modify(1, m, 1, p, m, -t * (n + 1));
            r1.modify(1, m, 1, 1, p - 1, t * (n + 1));
            r2.modify(1, m, 1, p, m, -t * (n + 1));
            int ans1 = min(l1.query(1, m, 1, 1, p - 1), l2.query(1, m, 1, p, m)) + abs(arr[1] - S);
            int ans2 = min(r1.query(1, m, 1, 1, p - 1), r2.query(1, m, 1, p, m)) + abs(arr[m] - S);
            // for (int i = 1; i <= n; i++){
            //     int ans1 = dpl[i][1][0] + abs(arr[i] - t) * (n + 1) + abs(arr[1] - s);
            //     int ans2 = dpr[i][1][0] + abs(arr[i] - t) * (n + 1) + abs(arr[n] - s);
            //     ans = min({ans, ans1, ans2});
            // }
            if (min(ans1, ans2) + n <= T)
                cout << "Yes\n";
            else cout << "No\n";
            l1.modify(1, m, 1, 1, p - 1, -t * (n + 1));
            l2.modify(1, m, 1, p, m, t * (n + 1));
            r1.modify(1, m, 1, 1, p - 1, -t * (n + 1));
            r2.modify(1, m, 1, p, m, t * (n + 1));
        }
        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...