树状数组【功能实现】

写之前先膜拜一下最近教我树状数组的大神orzorzorz..
【啊。。发现这里讲得很清楚= =...mark】

看了一下有关于树状数组的基础题,大概就是关于树状数组的原理运用以及基本的功能实现。
这里先把树状数组的功能理一下
1.点修改
2.区间和的查询
(论线段树和树状数组的区别....)

简要的说一下,要实现以上功能主要是要了解:
1.lowbit的作用
2.初始化:前缀和(详见代码①)
3.区间和的查询运用的区间的相关运算(什么区间加法,区间减法啥的),详见代码②

废话不说了要睡觉了嗯
扔上题目和代码嗯,原理的话等我某哪天组织好语言再来,以及poj3468
【问题描述】

    给定一数列,规定有两种操作,一是修改某个元素,二是求区间的连续和。

    输入数据第一行包含两个正整数n,m(n<=100000,m<=500000),以下是m行,

    每行有三个正整数k,a,b(k=0或1, a,b<=n).k=0时表示将a处数字加上b,k=1时表示询问区间[a,b]内所有数的和。对于每个询问输出对应的答案。



【输入样例】

    10 20

    0 1 10

    1 1 4

    0 6 6

    1 4 10

    1 8 9

    1 4 9

    0 10 2

    1 1 8

    0 2 10

    1 3 9

    0 7 8

    0 3 10

    0 1 1

    1 3 8

    1 6 9

    0 5 5

    1 1 8

    0 4 2

    1 2 8

    0 1 1



【输出样例】

    10

    6

    0

    6

    16

    6

    24

    14

    50

    41

 

#include<cstdio> 

#include<cstring> 

using namespace std; 

long long a[100001],n,m; 

int sum(int x){ 

    int ans=0; 

    for(;x;x-=x&-x) ans+=a[x];//lowbit的写法...给某个大神跪跪跪 

   return ans; 

} 

void add(int x,int d){ 

    for(;x<=n;x+=x&-x) a[x]+=d; 

} 

int main(){ 

    int i,j=0,s,k,t,x,y,d; 

    freopen("sum.in","r",stdin); 

    freopen("sum.out","w",stdout); 

      

    scanf("%d%d",&n,&m); 

    memset(a,0,sizeof(a));      

    for(i=0;i<m;i++){ 

        scanf("%d",&k); 

        if(k==0){ 

            scanf("%d%d",&x,&d); 

            add(x,d); 

        } 

        else{ 

            scanf("%d%d",&x,&y); 

            t=sum(y)-sum(x-1);//区间运算 ②

            printf("%d",t);        

        } 

    } 

    fclose(stdin);fclose(stdout); 

    return 0; 

}

 

 

由于这一题比较特殊,刚开始的a数组初始化为0,所以初始化不需要考虑打前缀和
这里说一下,如果要求输入a数组值,则需要维护一个b数组//因为这里需要修改单点的值,所以维护最初的数组是不行的
所以,b数组的初始化:
b[i]=b[i-1]+a[i];①//前缀和,方便区间的运算

你可能感兴趣的:(树状数组)