写模板,树状数组。

1 根据长度初始化, 单点更新, 区间查询。
可以查询区间和(输入为位置+数值),
可以查询区间内频次(输入为数值+频次1)。
2 根据输入数据线性初始化。
3 根据输入数据频次线性初始化,区间更新,单点查询。
根据差分后的数组求前缀和(单点查询)。

  class FenwickTree{
public:
    FenwickTree(int sz): sz_(sz){
        ft_.resize(sz_);
    }

    FenwickTree(vector<long long>& f){
        sz_ = int(f.size());
        ft_.assign(sz_, 0);
        for (int i = 1; i < sz_; ++i){
            ft_[i] += f[i];
            if (i + lowbit(i) < sz_){
                ft_[i + lowbit(i)] += ft_[i];
            }
        }
    }

    FenwickTree(vector<int>& s){
        sz_ = *max_element(s.begin() + 1, s.end()) + 1;
        ft_.resize(sz_);
        for (size_t i = 1; i < s.size(); ++i){
            ft_[s[i]] ++;
            if (s[i] + lowbit(s[i]) < sz_){
                ft_[s[i] + lowbit(s[i])] += ft_[s[i]];
            }
        }
    }

    void update(int pos, long long value){
        while (pos < sz_){
            ft_[pos] += value;
            pos += lowbit(pos);
        }
    }

    void update(int l, int r, long long value){
        update(l, value);
        update(r + 1, -value);
    }

    long long query(int p){
        assert(p < sz_);
        long long res = 0;
        while (p > 0){
            res += ft_[p];
            p -= lowbit(p);
        }
        return res;
    }

    long long query(int l, int r){
        assert(l <= r);
        return query(r) - query(l - 1);
    }


private:
    int sz_;
    vector<long long> ft_;


private:
    inline int lowbit(int x) {return (x & (-x));}
};
posted @   _Yxc  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示