算法-树状数组

用途:
1.给某个位置上数加一个数(单点修改)o(logn)
2.求某一个前缀和(区间查询)o(logn)

#include <bits/stdc++.h>

using namespace std;

const int N=100010;

int a[N],tr[N];
int n,m;
int k,x,y;

int lowbit(int x)//返回2^k(k为x二进制末尾连续0的个数)
{
    return x&-x;
}

void add(int x,int v)//加值操作
{
    for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=v;
}

int query(int x)//[1-x]的前缀和
{
    int res=0;
    for(int i=x;i>0;i-=lowbit(i)) res+=tr[i];
    return res;
}

int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) add(i,a[i]);//初始化
    while(m--)
    {
        cin>>k>>x>>y;
        if(k==0) cout<<query(y)-query(x-1)<<endl;//利用前缀和思想求某一段区间的和
        else add(x,y);
    }
    return 0;
}

如果想要x->y可以通过x+(-x)+y 来实现

posted @   Eric`  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示