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));}
};
标签:sz,ft,树状,int,lowbit,pos,long,数组,模板
From: https://www.cnblogs.com/yxcblogs/p/18096448