珂朵莉树

严格来说,珂朵莉树主要的用处是骗分 ——OI Wiki

class ODT {
    struct node {
        int l, r;
        mutable ll v;
        node(const int& il, const int& ir, const ll& iv) : l(il), r(ir), v(iv) {}
        inline bool operator<(const node& o) const { return l < o.l; }
    };
    set<node> odt;

public:
    // void init() {
        // cin >> n;
        // for (int i = 1; i <= n; ++i) {
            // int x;
            // cin >> x, odt.insert(node(i, i, x));
        // }
    // }

    auto split(int x) {
        if (x > n) return odt.end();
        auto it = --odt.upper_bound(node(x, 0, 0));
        if (it->l == x) return it;
        int l = it->l, r = it->r;
        ll v = it->v;
        odt.erase(it);
        odt.insert(node(l, x - 1, v));
        return odt.insert(node(x, r, v)).first;
    }

    void assign(int l, int r, ll v) {
        auto itr = split(r + 1), itl = split(l);
        odt.erase(itl, itr);
        odt.insert(node(l, r, v));
    }
    
    void add(int l, int r, ll v) {
        auto itr = split(r + 1), itl = split(l);
        for (; itl != itr; ++itl) itl->v += v;
    }
    
    ll kth_element(int l, int r, int k) {
        auto itr = split(r + 1), itl = split(l);
        vector<pair<ll, int>> V;
        for (; itl != itr; ++itl) V.push_back(make_pair(itl->v, itl->r - itl->l + 1));
        sort(V.begin(), V.end());
        for (auto x : V) {
            k -= x.second;
            if (k <= 0) return x.first;
        }
        return -1;
    }

    void query(int l, int r) {
        auto itr = split(r + 1), itl = split(l);
        ll ans = 0;
        for (; itl != itr; ++itl) {
            // itl->r - itl->l + 1    itl->v
            // sum += (itl->r - itl->l + 1) * itl->v;
        }
    }
};

例题

CF-896C

code

posted @ 2022-11-26 18:53  CKB2008  阅读(22)  评论(0编辑  收藏  举报