1 条题解

  • 0
    @ 2025-10-8 17:11:51
    #include <bits/stdc++.h>
    using namespace std;
    #define lc(p) tr[p].ls
    #define rc(p) tr[p].rs
    const int N = 1e5 + 10;
    struct node { int ls, rs, val, siz, laz, rnd; } tr[N];
    int rt, trlen;
    
    int newd(int v) { tr[++trlen] = {0, 0, v, 1, 0, rand()}; return trlen; }
    
    void pushup(int p) { tr[p].siz = tr[lc(p)].siz + tr[rc(p)].siz + 1; }
    
    void pushdown(int p) {
        if (tr[p].laz) {
            if (lc(p)) tr[lc(p)].laz += tr[p].laz, tr[lc(p)].val -= tr[p].laz;
            if (rc(p)) tr[rc(p)].laz += tr[p].laz, tr[rc(p)].val -= tr[p].laz;
            tr[p].laz = 0;
        }
    }
    
    void split(int p, int v, int &x, int &y) {
        if (p == 0) { x = y = 0; return; }
        pushdown(p);
        if (tr[p].val <= v) {
            x = p;
            split(rc(p), v, rc(x), y);
        } else {
            y = p;
            split(lc(p), v, x, lc(y));
        }
        pushup(p);
    }
    
    int merge(int x, int y) {
        if (!x || !y) return x + y;
        if (tr[x].rnd < tr[y].rnd) {
            pushdown(x);
            rc(x) = merge(rc(x), y);
            pushup(x);
            return x;
        } else {
            pushdown(y);
            lc(y) = merge(x, lc(y));
            pushup(y);
            return y;
        }
    }
    
    void ins(int v) {
        int x, y;
        split(rt, v, x, y);
        rt = merge(x, merge(newd(v), y));
    }
    
    void ex_merge(int &x, int y) {
        if (!y) return;
        pushdown(y);
        ex_merge(x, lc(y));
        ex_merge(x, rc(y));
        tr[y].ls = tr[y].rs = 0; tr[y].siz = 1;
        int l, r; split(x, tr[y].val, l, r);
        x = merge(l, merge(y, r));
    }
    
    int getval(int p, int k) {
        pushdown(p);
        if (k == tr[lc(p)].siz + 1) return tr[p].val;
        if (k <= tr[lc(p)].siz) return getval(lc(p), k);
        else return getval(rc(p), k - tr[lc(p)].siz - 1);
    }
    
    int main() {
        int n, m; scanf("%d%d", &n, &m);
        rt = trlen = 0;
        for (int i = 1, v; i <= n; ++i) scanf("%d", &v), ins(v);
        for (int i = 1, op, k, v; i <= m; ++i) {
            scanf("%d", &op);
            if (op == 1) {
                scanf("%d", &k);
                printf("%d\n", getval(rt, k));
            } else {
                scanf("%d", &v);
                int x, y, z;
                split(rt, v, x, y);
                if (y) tr[y].laz += v, tr[y].val -= v;
                split(y, v, y, z);
                ex_merge(x, y);
                rt = merge(x, z);
            }
        }
        return 0;
    }
    
    • 1

    *【FHQ Treap】[Lydsy1706月赛]K小值查询

    信息

    ID
    6592
    时间
    1000ms
    内存
    256MiB
    难度
    7
    标签
    递交数
    80
    已通过
    16
    上传者