• 权值线段树


    权值线段树就是一棵线段树,不过存的值不是和或积或最大值一类的,而是这一区间上“数”的个数。

    这里就讲一下动态开点的。

    1,存储

    struct seg_tree{
        int val, lson, rson;//个数、左孩子编号、右孩子编号
    }st[MAX];

     2,加点

    void add(int &x,int l, int r, int v) {
        if (!x) x = ++tot;//动态开点 
        st[x].val++;
        if (l == r) return;
        ll mid = (l + r) >> 1;
        if (mid >= v) add(st[x].lson, l, mid, v); 
        else add(st[x].rson, mid + 1, r, v);
    }

    它有什么功能呢?

    其实它就是一个桶,桶能做的它都能做。

    1,查询v出现的次数(单点查询)

    void ask(int x, int l, int r, int v) {
        if (!x) return 0;
        if (l == r) return st[x].val;
        int mid = (l + r) >> 1;
        if (v <= mid) return ask(st[x].lson, l, mid, v);
        else return ask(st[x].rson, mid + 1, r, v);
    }

    2,查询[l, r]中的数出现的次数

    以下代码是求[i, j]中的数出现的次数

    int ask(int x, int l, int r, int i, int j) {
        if (!x) return 0;
        if (i == l && r == j) {
            return st[x].val;
        }
        int mid = (l + r) >> 1;
        if (j <= mid) return ask(st[x].lson, l, mid, i, j);
        else if (i > mid) return ask(st[x].rson, mid + 1, r, i, j);
        else return ask(st[x].lson, l, mid, i, mid) + ask(st[x].rson, mid + 1, r, mid + 1, j);
    }

    3,查询区间第k大(小)

    int ask(int x, int l, int r, int k) {
        if (l == r) return l;
        int mid = (l + r) >> 1;
        if (k <= st[st[x].lson].val) return ask(st[x].lson, l, mid, k);
        else return ask(st[x].rson, mid + 1, r, k st[st[x].lson].val);
    }

    大概就以上几种用法,相信你都学会啦。

    权值线段树也没什么例题,但它是很多高端数据结构的基础。

  • 相关阅读:
    梦断代码阅读笔记03
    梦断代码阅读笔记01
    构建之法阅读笔记03
    《构建之法——现代软件工程》读书笔记(一)
    构建之法阅读笔记02
    TypeError: only integer scalar arrays can be converted to a scalar index
    LeetCode Easy: 33. Search in Rotated Sorted Array
    LeetCode Medium: 31. Next Permutation
    LeetCode Medium: 29. Divide Two Integers
    python中merge、concat用法
  • 原文地址:https://www.cnblogs.com/zcr-blog/p/11992303.html
Copyright © 2020-2023  润新知