Submission #1330429

#TimeUsernameProblemLanguageResultExecution timeMemory
1330429edoRMQ (NOI17_rmq)C++20
23 / 100
1 ms348 KiB
#include <bits/stdc++.h>

using namespace std;
using ll = long long;

const int inf = 1e9;

struct Seg {
    int n;
    vector<int> mn;
    vector<int> mx;

    Seg(int n) : n(n), mn(4 * n, inf), mx(4 * n, -1) {}

    void updMax(int node, int start, int end, int l, int r, int v) {
        if(start > end || start > r || end < l) return;
        if(start >= l && end <= r) {
            mx[node] = max(mx[node], v);
            return;
        }
        int mid = (start + end) / 2;
        updMax(node << 1, start, mid, l, r, v);
        updMax(node << 1 | 1, mid + 1, end, l, r, v);
    }

    void buildMin(int node, int start, int end, const vector<int>& b) {
        if(start == end) {
            mn[node] = b[start];
            return;
        }
        int mid = (start + end) / 2;
        buildMin(node << 1, start, mid, b);
        buildMin(node << 1 | 1, mid + 1, end, b);
        mn[node] = min(mn[node << 1], mn[node << 1 | 1]);
    }

    void kill(int node, int start, int end, int id) {
        if(start == end) {
            mn[node] = inf;
            return;
        }
        int mid = (start + end) / 2;
        if(id <= mid) kill(node << 1, start, mid, id);
        else kill(node << 1 | 1, mid + 1, end, id);
        mn[node] = min(mn[node << 1], mn[node << 1 | 1]);
    }

    void push_max(int node, int start, int end, int currMax, vector<int>& b) {
        currMax = max(currMax, mx[node]);
        if(start == end) {
            b[start] = currMax;
            return;
        }
        int mid = (start + end) / 2;
        push_max(node << 1, start, mid, currMax, b);
        push_max(node << 1 | 1, mid + 1, end, currMax, b);
    }

    int find(int node, int start, int end, int l, int r, int v) {
        if(start > end || start > r || end < l || mn[node] > v) return -1;
        if(start == end) return start;
        int mid = (start + end) / 2;
        int res = find(node << 1, start, mid, l, r, v);
        if(res == -1) res = find(node << 1 | 1, mid + 1, end, l, r, v);
        return res;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, q;
    cin >> n >> q;
    vector<int> L(n), R(n, n - 1);
    vector<char> have(n, 0);

    Seg seg(n);
    for (int i = 0; i < q; ++i) {
        int l, r, v;
        cin >> l >> r >> v;
        seg.updMax(1, 0, n - 1, l, r, v);
        L[v] = max(L[v], l); 
        R[v] = min(R[v], r); 
        have[v] = 1;
    }
    auto die = [&]() {
        for (int j = 0; j < n; ++j) {
            cout << -1 << " ";
        }
        exit(0);
    };
    for (int i = 0; i < n; ++i)
        if(have[i] && L[i] > R[i]) 
            die();            

    vector<int> B(n);
    seg.push_max(1, 0, n - 1, 0, B);
    seg.buildMin(1, 0, n - 1, B);

    vector<tuple<int, int, int>> vals(n);
    for (int i = 0; i < n; ++i) vals[i] = {i, L[i], R[i]};        
    sort(vals.begin(), vals.end(), [](const tuple<int, int, int>& a, const tuple<int, int, int>& b) { return get<2>(a) < get<2>(b);});

    vector<int> res(n, -1);
    for (int i = 0; i < n; ++i) {
        auto &[v, l, r] = vals[i];
        int p = seg.find(1, 0, n - 1, l, r, v);
        if(~p) {
            res[p] = v;
            seg.kill(1, 0, n - 1, p);
        }
        else die();
    }

    for (int &i : res)
        cout << i << " ";
    return 0;
}

#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...