【数据结构】树状数组的几种用法

用法:

  1. 单点修改
  2. 区间修改
  3. 单点查询
  4. 区间查询

模板题:

洛谷P3374:

https://www.luogu.org/problemnew/show/P3374

洛谷P3368:

https://www.luogu.org/problemnew/show/P3368

代码:

洛谷P3374:

#include<iostream>
using namespace std;
int n,m;
int tree[2000010];
int lowbit(int k)
{
    return k & -k;//补码原则 
}
void add(int x,int k)
{
    while(x<=n)
    {
        tree[x]+=k;
        x+=lowbit(x);//根据二进制原理加上本身的lowbit等于下一个值 
    }
}
int sum(int x)
{
    int ans=0;
    while(x!=0)
    {
        ans+=tree[x];
        x-=lowbit(x);
    }
    return ans; 
}
int main()
{
    std::ios::sync_with_stdio(false);//取消cincout的时间
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        int x;
        cin>>x;
        add(i,x);
    }
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        if(a==1)
        add(b,c);//在b的位置加上c 
        if(a==2)
        cout<<sum(c)-sum(b-1)<<endl;//前缀和相减 
    }
} 
View Code

洛谷P3368:

#include<iostream>
using namespace std;
int n,m;
int tree[500010];
int num[500010];
int lowbit(int k)
{
    return k & -k;//补码原则 
}
void add(int x,int k)
{
    while(x<=n)
    {
        tree[x]+=k;
        x+=lowbit(x);//根据二进制原理加上本身的lowbit等于下一个值 
    }
}
int sum(int x)
{
    int ans=0;
    while(x!=0)
    {
        ans+=tree[x];
        x-=lowbit(x);
    }
    return ans; 
}
int main()
{
    std::ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    cin>>num[i];
    for(int i=1;i<=m;i++)
    {
        int a;
        cin>>a;
        if(a==1)
        {
            int x,y,z;
            cin>>x>>y>>z;
            add(x,z);
            add(y+1,-z);//把前面加上的多余减掉 
        }
        if(a==2)
        {
            int x;
            cin>>x;
            cout<<num[x]+sum(x)<<endl;//把原来的数加上后来加的 
        } 
    }
} 
View Code

后记:

原来就上过一遍这个了

但是当时没有弄懂二进制和lowbit这些关系啥的

导致并不是太懂

现在再上一遍到是水到渠成了

posted @ 2018-07-07 21:29  Nanchtiy  阅读(263)  评论(0编辑  收藏  举报