제출 #1343375

#제출 시각아이디문제언어결과실행 시간메모리
1343375maxiedHedgehog Daniyar and Algorithms (IZhO19_sortbooks)C++20
21 / 100
1872 ms198144 KiB
#include <bits/stdc++.h>
using namespace std;
using i64 = int;

struct n1{
    int s, e, m;
    i64 mn = INT_MAX;
    n1 *lhs, *rhs;
    n1(int _s, int _e, vector<i64> &v) : s(_s), e(_e), m((_s + _e) >> 1){
        if (s == e){
            mn = v[s];
            return;
        }
        lhs = new n1(s, m, v);
        rhs = new n1(m + 1, e, v);
        mn = min(lhs->mn, rhs->mn);
    }
    i64 query(int l, int r){
        if (l <= s && e <= r){
            return mn;
        }
        i64 res = INT_MAX;
        if (l <= m){
            res = min(res, lhs->query(l, r));
        }
        if (r >= m + 1){
            res = min(res, rhs->query(l, r));
        }
        return res;
    }
};

struct n2{
    int s, e, m;
    int mx = -INT_MAX;
    n2 *lhs, *rhs;
    n2(int _s, int _e, vector<i64> &v) : s(_s), e(_e), m((_s + _e) >> 1){
        if (s == e){
            mx = v[s];
            return;
        }
        lhs = new n2(s, m, v);
        rhs = new n2(m + 1, e, v);
        mx = max(lhs->mx, rhs->mx);
    }
    int query(int l, int r){
        if (l <= s && e <= r){
            return mx;
        }
        int res = -INT_MAX;
        if (l <= m){
            res = max(res, lhs->query(l, r));
        }
        if (r >= m + 1){
            res = max(res, rhs->query(l, r));
        }
        return res;
    }
};

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

    // range small = x
    // mood = k
    // range big = biggest <= k - x
    // anything <= big is unfrozen
    // frozen position must in correct spot
    //
    // frozen position is always on the right of unfrozen position
    // and all frozen position must be in sorted order
    // 1. range find smallest
    // 2. calculate the biggest possible
    // 3. binary search last index i s.t. [l, i] are all unfrozen ie. they are <= biggest possible mover
    // 4. check if i + 1 .. r is sorted
    // 
    // 1 is range min query (trivial)
    // 3 is bsta on segtree (idk not so trivial) ((dont bianry search since that's the 2e5 subtask))
    // i'll do this later
    // 4 is range sorted query (trivial)
    //
    // if left max is more than biggest go left (cuz right will include it)
    // else go right
    // l == r return l

    int n, m;
    cin >> n >> m;
    if (n <= 500 && m <= 500){
// range small = x
    // mood = k
    // range big = biggest <= k - x
    // anything <= big is unfrozen
    // frozen position must in correct spot
    //
    // frozen position is always on the right of unfrozen position
    // and all frozen position must be in sorted order
    // 1. range find smallest
    // 2. calculate the biggest possible
    // 3. binary search last index i s.t. [l, i] are all unfrozen ie. they are <= biggest possible mover
    // 4. check if i + 1 .. r is sorted
    // 
    // 1 is range min query (trivial)
    // 3 is bsta on segtree (idk not so trivial) ((dont bianry search since that's the 2e5 subtask))
    // i'll do this later
    // 4 is range sorted query (trivial)
    //
    // if left max is more than biggest go left (cuz right will include it)
    // else go right
    // l == r return l

    vector<int> v(n);
    for (int i = 0; i < n; i++){
        cin >> v[i];
    }
    n1 *rmin = new n1(0, n - 1, v);
    n2 *rmax = new n2(0, n - 1, v);
    vector<int> psort(n);
    for (int i = 0; i < n - 1; i++){
        psort[i + 1] = psort[i] + (v[i] <= v[i + 1]);
    }
    auto sorted = [&](int l, int r) -> int{
        return (r - l) == (psort[r] - psort[l]);
    };
    /*
    // check min
    for (int i = 0; i < n; i++){
        for (int j = i + 1; j < n; j++){
            cout << "[";
            for (int k = i; k <= j; k++){
                cout << v[k] << ' ';
            }
            cout << "] = ";
            cout << rmin->query(i, j) << '\n';
        }
    }
    // check max
    for (int i = 0; i < n; i++){
        for (int j = i + 1; j < n; j++){
            cout << "[";
            for (int k = i; k <= j; k++){
                cout << v[k] << ' ';
            }
            cout << "] = ";
            cout << rmax->query(i, j) << '\n';
        }
    }
    */
    for (int l, r, k; m--;){
        cin >> l >> r >> k;
        l--, r--;
        vector<int> cur = v;
        for (int i = 0; i < (r - l + 1); i++){
            for (int j = l; j < r; j++){
                if (cur[j] > cur[j + 1] && cur[j] + cur[j + 1] <= k){
                    swap(cur[j], cur[j + 1]);
                }
            }
        }
        bool s = true;
        for (int i = l; i < r; i++){
            if (cur[i] > cur[i + 1]){
                s = false;
                break;
            }
        }
        cout << (s ? "1" : "0") << '\n';
    }
    return 0;
    for (int l, r, k; m--;){
        cin >> l >> r >> k;
        l--, r--;
        int mn = rmin->query(l, r);
        int can = k - mn;
        if (mn > can || v[l] > can){
            cout << (sorted(l, r) ? "1" : "0") << '\n';
            continue;
        }
        int lo = l;
        while (lo + 1 < r && v[lo + 1] <= can){
            lo++;
        }
        /*
        int lo = l, hi = r;
        // mx <= can
        // TTTTFFF
        while (lo < hi){
            int mid = (lo + hi + 1) >> 1;
            if (rmax->query(l, mid) <= can){
                lo = mid;
            }
            else{
                hi = mid - 1;
            }
        }
        */
        if (lo == r){
            cout << "1" << '\n';
            continue;
        }
        cout << (sorted(lo + 1, r) ? "1" : "0") << '\n';
    }
        return 0;
    }
    vector<i64> v(n);
    for (int i = 0; i < n; i++){
        cin >> v[i];
    }
    n1 *rmin = new n1(0, n - 1, v);
    n2 *rmax = new n2(0, n - 1, v);
    vector<int> psort(n);
    for (int i = 0; i < n - 1; i++){
        psort[i + 1] = psort[i] + (v[i] <= v[i + 1]);
    }
    auto sorted = [&](int l, int r) -> int{
        return (r - l) == (psort[r] - psort[l]);
    };
    /*
    // check min
    for (int i = 0; i < n; i++){
        for (int j = i + 1; j < n; j++){
            cout << "[";
            for (int k = i; k <= j; k++){
                cout << v[k] << ' ';
            }
            cout << "] = ";
            cout << rmin->query(i, j) << '\n';
        }
    }
    // check max
    for (int i = 0; i < n; i++){
        for (int j = i + 1; j < n; j++){
            cout << "[";
            for (int k = i; k <= j; k++){
                cout << v[k] << ' ';
            }
            cout << "] = ";
            cout << rmax->query(i, j) << '\n';
        }
    }
    */
    for (int l, r; m--;){
        i64 k;
        cin >> l >> r >> k;
        l--, r--;
        i64 mn = rmin->query(l, r);
        i64 can = k - mn;
        if (mn > can || v[l] > can){
            cout << (sorted(l, r) ? "1" : "0") << '\n';
            continue;
        }
        int lo = l;
        while (lo + 1 < r && v[lo + 1] <= can){
            lo++;
        }
        /*
        int lo = l, hi = r;
        // mx <= can
        // TTTTFFF
        while (lo < hi){
            int mid = (lo + hi + 1) >> 1;
            if (rmax->query(l, mid) <= can){
                lo = mid;
            }
            else{
                hi = mid - 1;
            }
        }
        */
        if (lo == r){
            cout << "1" << '\n';
            continue;
        }
        cout << (sorted(lo + 1, r) ? "1" : "0") << '\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...