Submission #1343272

#TimeUsernameProblemLanguageResultExecution timeMemory
1343272maxiedHedgehog Daniyar and Algorithms (IZhO19_sortbooks)C++20
0 / 100
1869 ms288080 KiB
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

struct n1{
    int s, e, m;
    int mn = INT_MAX;
    n1 *lhs, *rhs;
    n1(int _s, int _e, vector<int> &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);
    }
    int query(int l, int r){
        if (l <= s && e <= r){
            return mn;
        }
        int 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<int> &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;
    }
};

struct n3{
    int s, e, m;
    bool sorted;
    n3 *lhs, *rhs;
    n3(int _s, int _e, vector<int> &v) : s(_s), e(_e), m((_s + _e) >> 1){
        if (s == e){
            sorted = true;
            return;
        }
        lhs = new n3(s, m, v);
        rhs = new n3(m + 1, e, v);
        sorted = (lhs->sorted && rhs->sorted);
        if (sorted){
            sorted = (v[lhs->e] < v[rhs->s]);
        }
    }
    bool query(int l, int r, vector<int> &v){
        if (l <= s && e <= r){
            return sorted;
        }
        if (l <= m && r >= m + 1){
            return lhs->query(l, r, v) && rhs->query(l, r, v) && v[m] <= v[m + 1];
        }
        else if (l <= m){
            return lhs->query(l, r, v);
        }
        else {
            assert(r >= m + 1);
            return rhs->query(l, r, v);
        }
    }
};

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
    // are there working marks
    // if ihad my disjoint sparse table template i'd use it for o(1) min but ok
    // !! no updates

    int n, m;
    cin >> n >> m;
    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);
    n3 *rsrt = new n3(0, n - 1, v);
    /*
    // 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';
        }
    }
    // check sort
    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 << (rsrt->query(i, j, v) ? "YES" : "NO") << '\n';
        }
    }
    */
    for (int l, r, k; m--;){
        cin >> l >> r >> k;
        l--, r--;
        int mn = rmin->query(l, r);
        int can = k - mn;
        if (v[l] > can){
            cout << (rsrt->query(l, r, v) ? "1" : "0") << '\n';
            continue;
        }
        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 << (rsrt->query(lo + 1, r, v) ? "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...