树状数组

Posted shzyk

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树状数组相关的知识,希望对你有一定的参考价值。

 

主要要注意lowbit函数

然后add时向右跑,check时向左跑(此处的add只能单点修改)

#include<iostream>//从洛谷3374直接复制来的
#include<cstdio>
using namespace std;
#define lowbit(x) (x&(-(x)))
void read(int &x);
int n,m;
int a[500005];
void add(int s,int t)//给s+t 
{
    int ss=s;
    for(;ss<=n;ss+=lowbit(ss)) a[ss]+=t;
}
int check(int s,int t)//左闭右闭
{
    int res=0;
    int ret=0;
    int ss=s-1;
    int tt=t;
    for(;tt;tt-=lowbit(tt)) ret+=a[tt];
    for(;ss;ss-=lowbit(ss)) res+=a[ss];
    return ret-res;
}
int main()
{
    Read(n),Read(m);
    int w;
    for(int i=1;i<=n;i++) Read(w),add(i,w);
    for(int i=1;i<=m;i++)
    {
        int e,s,t;
        RRead(e),Read(s),Read(t);
        if(e==1) add(s,t);
        if(e==2) printf("%d
",check(s,t));
    }
    return 0;
}
void Read(int &x)
{
    x=0;
    char c=getchar();
    int i=1;
    while(c<0 or c>9)
    {
        if(c==-) i=-1;
        c=getchar();
    }
    while(c>=0 and c<=9)
    {
        x=x*10+c-0;
        c=getchar();
    }
    x*=i;
}

若想实现区间修改,则要结合差分(不过这就只能单点查询了)

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 #define lowbit(x) ((x)&(-(x)))
 5 void read(int &x);
 6 int n,m;
 7 int a[500005];
 8 int c[500005];
 9 void add(int s,int t)//给s+t 
10 {
11     int ss=s;
12     for(;ss<=n;ss+=lowbit(ss)) a[ss]+=t;
13 }
14 int check(int s,int t)//左闭右闭
15 {
16     int res=0;
17     int ret=0;
18     int ss=s-1;
19     int tt=t;
20     for(;tt;tt-=lowbit(tt)) ret+=a[tt];
21     for(;ss;ss-=lowbit(ss)) res+=a[ss];
22     return ret-res;
23 }
24 int main()
25 {
26     read(n),read(m);
27     c[0]=0;
28     for(int i=1;i<=n;i++) read(c[i]);
29     for(int i=n;i>=1;i--) c[i]=c[i]-c[i-1];
30     //for(int i=1;i<=n;i++) printf("*%d",a[i]);
31     for(int i=1;i<=n;i++) add(i,c[i]);
32     //for(int i=1;i<=n;i++) printf("*%d",check(1,i));
33     for(int i=1;i<=m;i++)
34     {
35         int e,r;
36         read(e);
37         if(e==1) 
38         {
39             int x,y,z;
40             read(x),read(y),read(z);
41             add(x,z);
42             add(y+1,(z*(-1)));
43         }
44         if(e==2) read(r),printf("%d
",check(1,r));
45     }
46     return 0;
47 }
48 void read(int &x)
49 {
50     x=0;
51     char c=getchar();
52     int i=1;
53     while(c<0 or c>9)
54     {
55         if(c==-) i=-1;
56         c=getchar();
57     }
58     while(c>=0 and c<=9)
59     {
60         x=x*10+c-0;
61         c=getchar();
62     }
63     x*=i;
64 }

所以最强大的还是线段树了

以上是关于树状数组的主要内容,如果未能解决你的问题,请参考以下文章

数据结构之树状数组从零认识树状数组

树状数组和线段树有啥区别?

树状数组

树状数组

树状数组

如何利用树状数组修改一个区间?