[模板][数据结构] 树状数组 Binary Index Tree/Fenwick Tree
Templates 数据结构 BIT
Lastmod: 2022-01-06 周四 23:51:21

树状数组 Binary Index Tree/Fenwick Tree

1d 单点修改,区间询问

// T must + -
// id 1~n
template<typename T,size_t M,typename OpPlus=plus<T>,typename OpMinus=minus<T>>
struct BIT
{
    static int lowbit(int x) { return x&(-x); }
    constexpr static OpPlus opp{};
    constexpr static OpMinus opm{};
    static T tmp[M+1];

    T tree[M+1]; // tree[i] -> sum of [i-lowbit(i)+1,i]
    int n;
    void init(int n_)
    {
        n=n_;
        for(int i=1;i<=n;i++) tree[i]=T(0);
    }
    void init(int n_,T v[]) // v[0 ~ n_-1]
    {
        n=n_; tmp[0]=T(0);
        for(int i=1;i<=n;i++) tmp[i]=opp(tmp[i-1],v[i]);
        for(int i=1;i<=n;i++) tree[i]=opm(tmp[i],tmp[i-lowbit(i)]);
        // for(int i=0;i<n;i++) add(i,v[i]);
    }
    void add(int p,T V)
    { for(;p<=n;p+=lowbit(p)) tree[p]=opp(tree[p],V); }
    T sum(int p)
    {
        T ans(0);
        for(;p;p-=lowbit(p)) ans=opp(ans,tree[p]);
        return ans;
    }
    T sum(int l,int r) { return opm(sum(r),sum(l-1)); }
};

2d 单点修改,矩形询问

// T must define + -
// id x:1~n y:1~m
template<typename T,
         size_t MN,
         size_t MM,
         typename OpPlus=plus<T>,
         typename OpMinus=minus<T>>
struct BIT
{
    static int lowbit(int x) { return x&(-x); }
    constexpr static OpPlus opp{};
    constexpr static OpMinus opm{};

    T tree[MN+1][MM+1]; // tree[i] -> sum of [i-lowbit(i)+1,i]
    int n,m;
    void init(int n_,int m_)
    {
        n=n_; m=m_;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++) tree[i][j]=T(0);
    }
    void init(int n_,int m_,T v[MN][MM]) // v[0 ~ n_-1]
    {
        init(n_,m_);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++) add(i,j,v[i][j]);
    }
    void add(int x,int y,T V)
    { 
        for(;x<=n;x+=lowbit(x)) 
            for(int i=y;i<=m;i+=lowbit(i)) tree[x][i]=opp(tree[x][i],V); 
    }
    T sum(int x,int y)
    {
        T ans(0);
        for(;x;x-=lowbit(x)) 
            for(int i=y;i;i-=lowbit(i)) ans=opp(ans,tree[x][i]);
        return ans;
    }
    T sum(int minx,int maxx,int miny,int maxy)
    {
        return opm(opp(sum(maxx,maxy),sum(minx-1,miny-1)),
            opp(sum(maxx,miny-1),sum(minx-1,maxy)));
    }
};
Prev: [模板] 计时 Timing
Next: [模板] 对拍程序