树状数组

Posted cj-gjh

tags:

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

树状数组相信大家都听说过,就是一大堆操作,lowbit然后附上一堆操作。具体就不说了

 

例题

例1:洛谷 模板1

技术分享图片
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<math.h>
 5 #define ll long long
 6 #define file(a) freopen(a".in","r",stdin);//freopen(a".out","w",stdout);
 7 const int maxn=500000+10;
 8 inline int gi(){
 9     int sum=0,f=1;char ch=getchar();
10     while(ch>9 || ch<0){if(ch==-)f=-1;ch=getchar();}
11     while(ch>=0 && ch<=9){sum=sum*10+ch-0;ch=getchar();}
12     return sum*f;
13 }
14 inline ll gl(){
15     ll sum=0,f=1;char ch=getchar();
16     while(ch>9 || ch<0){if(ch==-)f=-1;ch=getchar();}
17     while(ch>=0 && ch<=9){sum=sum*10+ch-0;ch=getchar();}
18     return sum*f;
19 }
20 ll c[maxn],a[maxn];
21 int n;
22 int lowbit(int x){
23     return x&(-x);
24 }
25 void Add(int x,ll d){
26     while(x<=n){
27         c[x]+=d;
28         x+=lowbit(x);
29     }
30 }
31 ll sum(int x){
32     ll ans=0;
33     while(x){
34         ans+=c[x];
35         x-=lowbit(x);
36     }
37     return ans;
38 }
39 int main(){
40     file("read");
41     int i,j,m;
42     n=gi();m=gi();
43     for(i=1;i<=n;i++){
44         a[i]=gl();
45         Add(i,a[i]);
46     }
47     for(i=1;i<=m;i++){
48         int op=gi(),x=gi();
49         if(op==1){
50             ll k=gl();
51             Add(x,k);
52         }
53         else{
54             int y=gi();
55             printf("%lld\n",sum(y)-sum(x-1));
56         }
57     }
58     return 0;
59 }
60 /*
61 输入格式:
62 第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。
63 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。
64 接下来M行每行包含3个整数,表示一个操作,具体如下:
65 操作1: 格式:1 x k 含义:将第x个数加上k
66 操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和
67 输出格式:
68 输出包含若干行整数,即为所有操作2的结果。
69 */ 
例1

 

例2:洛谷 模板2

技术分享图片
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<math.h>
 5 #define ll long long
 6 #define file(a) freopen(a".in","r",stdin);//freopen(a".out","w",stdout);
 7 const int maxn=500000+10; 
 8 inline int gi(){
 9     int sum=0,f=1;char ch=getchar();
10     while(ch>9 || ch<0){if(ch==-)f=-1;ch=getchar();}
11     while(ch>=0 && ch<=9){sum=sum*10+ch-0;ch=getchar();}
12     return sum*f;
13 }
14 inline ll gl(){
15     ll sum=0,f=1;char ch=getchar();
16     while(ch>9 || ch<0){if(ch==-)f=-1;ch=getchar();}
17     while(ch>=0 && ch<=9){sum=sum*10+ch-0;ch=getchar();}
18     return sum*f;
19 }
20 int n;
21 ll c[maxn],a[maxn];
22 int lowbit(int x){
23     return x&(-x);
24 }
25 void Add(int x,ll d){
26     while(x<=n){
27         c[x]+=d;
28         x+=lowbit(x);
29     }
30 }
31 ll sum(int x){
32     ll ans=0;
33     while(x){
34         ans+=c[x];
35         x-=lowbit(x);
36     }
37     return ans;
38 }
39 int main(){
40     file("read");
41     int i,j,m;
42     n=gi();m=gi();
43     for(i=1;i<=n;i++){
44         a[i]=gl();
45         Add(i,a[i]-a[i-1]);
46     }
47     for(i=1;i<=m;i++){
48         int op=gi(),x=gi();
49         if(op==1){
50             int y=gi();ll k=gl();
51             Add(x,k);
52             Add(y+1,-k);
53         }
54         else{
55             printf("%lld\n",sum(x));
56         }
57     }
58     return 0;
59 }
例2

 

例3:洛谷 逆序对

技术分享图片
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<math.h>
 5 #include<algorithm>
 6 using namespace std;
 7 #define ll long long
 8 #define file(a) freopen(a".in","r",stdin);//freopen(a".out","w",stdout);
 9 const int maxn=40000+10;
10 inline int gi(){
11     int sum=0,f=1;char ch=getchar();
12     while(ch>9 || ch<0){if(ch==-)f=-1;ch=getchar();}
13     while(ch>=0 && ch<=9){sum=sum*10+ch-0;ch=getchar();}
14     return sum*f;
15 }
16 int n;
17 int a[maxn],b[maxn],c[maxn];
18 int lowbit(int x){
19     return x&(-x);
20 }
21 void Add(int x,int d){
22     while(x<=n){
23         c[x]+=d;
24         x+=lowbit(x);
25     }
26 }
27 int sum(int x){
28     int ans=0;
29     while(x){
30         ans+=c[x];
31         x-=lowbit(x);
32     }
33     return ans;
34 }
35 int main(){
36     file("read");
37     int i,j,k,m;
38     int ans=0;
39     n=gi();
40     for(i=1;i<=n;i++)a[i]=b[i]=gi();
41     sort(b+1,b+n+1);
42     for(i=1;i<=n;i++)
43         a[i]=lower_bound(b+1,b+n+1,a[i])-b;
44     for(i=1;i<=n;i++){
45         Add(a[i],1);
46         ans+=i-sum(a[i]);
47     }
48     printf("%d\n",ans);
49     return 0;
50 }
例3

 

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

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

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

树状数组

树状数组

树状数组

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