zoukankan      html  css  js  c++  java
  • 权值线段树

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

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

    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);
    }

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

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

  • 相关阅读:
    Excel中删除含有空值的整行或是整列
    Power Pivot(二)
    Power Pivot(一)
    携程数据清洗
    Matplotlib基础绘图
    Pandas 数据清洗常见方法
    天猫美妆数据清洗步骤概括
    淘宝美妆双十一数据可视化(下)
    淘宝美妆双十一数据清洗(上)
    乐高天猫旗舰店数据分析
  • 原文地址:https://www.cnblogs.com/zcr-blog/p/11992303.html
Copyright © 2011-2022 走看看