Editorial for Các đoạn số nguyên


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Author: hazzu

#include <bits/stdc++.h>
#define taskname "olp0051"
using namespace std;

struct Line { int l, r, c; };
int nTest = 1;

class SegTree {
private:
    int sz;
    vector<int> ST; 
    vector<int> Lazy;

public:
    SegTree(int sz) {
        this->sz = sz;
        ST.assign(4 * sz + 1, 0);
        Lazy.assign(4 * sz + 1, 0);
    }
    void push_down(int id, int l, int r) {
        if (Lazy[id] == 0) return;
        ST[id] = (r - l + 1);
        if (l < r) {
            Lazy[id << 1] = Lazy[id];
            Lazy[id << 1 | 1] = Lazy[id];
        }
        Lazy[id] = 0;
    }
    int combine(int l, int r) {
        return l + r;
    }
    void update(int id, int l, int r, int u, int v) {
        push_down(id, l, r);
        if (r < u || v < l) return ;
        if (u <= l && r <= v) {
            Lazy[id] = 1;
            return push_down(id, l, r);
        }
        int m = (l + r) >> 1;
        update(id << 1, l, m, u, v);
        update(id << 1 | 1, m + 1, r, u, v);
        ST[id] = combine(ST[id << 1], ST[id << 1 | 1]);
    }
    int get(int id, int l, int r, int u, int v) {
        push_down(id, l, r);
        if (r < u || v < l) return 0;
        if (u <= l && r <= v) return ST[id];
        int m = (l + r) >> 1;
        return combine(get(id << 1, l, m, u, v), get(id << 1 | 1, m + 1, r, u, v));
    } 

    int find(int u, int v, int k) {
        int l = u, r = v;
        if (1 - get(r, v) >= k) return r;
        while (l + 1 < r) {
            int m = (l + r) >> 1;
            if ((v - m + 1) - get(m, v) >= k) l = m;
            else r = m; 
        }
        return l;
    }

    void update(int l, int r) { update(1, 1, sz, l, r); }
    int get(int l, int r) { return get(1, 1, sz, l, r); }
};

void Input() {
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    if (fopen(taskname".inp", "r")) {
        freopen(taskname".inp", "r", stdin);
        freopen(taskname".out", "w", stdout);
    }
    cin >> nTest;
}

void Solve() {
    int n; cin >> n;
    vector<Line> a(n);
    for (auto &i: a) {
        cin >> i.l >> i.r >> i.c;
        i.l++;
        i.r++;
    }
    sort(a.begin(), a.end(), [](Line x, Line y) {
        return x.r < y.r;
    });

    SegTree st(50010);

    int ans = 0;
    for (auto &i: a) {
        int k = st.get(i.l, i.r);
        if (k < i.c) {
            ans += i.c - k;
            int p = st.find(i.l, i.r, i.c - k);
            st.update(p, i.r);
        }
    }

    cout << ans;
}

int main(){
    Input();
    while (nTest--) Solve();
    return 0;
}

Comments