数据结构-树状数组(二)

复习笔记-树状数组(二)

树状数组(一)

略微进阶的操作

在树状数组(一)中,身为懒得打线段树(有时候都未必会打)的蒟蒻,我安利了一波树状数组,并且介绍了区间查询和单点修改的基本操作。那么,对基础的树状数组进行一些修改,结合差分,就可以同时进行区间修改和单点查询。

差分数组

存储方式

差分数组是相较于前缀和的一种截然相反的存储方式,前缀和的每个数表示原数组的前缀和,而差分数组的每个数表示原数组这个数和上一个数的差,也就是说

C1=A1

Cx=Ax-Ax-1

那么容易推出

C1+C2+...+Cm=Am

也就是说,差分数组元素的前缀和等于原数组该元素的值,这就是我说它与前缀和截然相反的第一个原因。

优势

差分数组由于每个数存的是与上一个数的差,可以理解成存的是数据的波动。那么,需要区间修改时,也就相当于区间内波动不变,区间左端波动上升,区间右端波动下降。这样就可以用O(1)复杂度完成区间修改。也就是说

如果把第x到第y加上k,只需要把差分数组第x个元素+k,第y+1个元素-k,就相当于完成了区间修改,只需要修改两处。

这是差分数组的修改的基础代码

1 void add(int x,int y,int k){
2     c[x] += k;
3     c[y + 1] -= k;
4 }

综上,差分数组可以O(1)完成区间修改。由于前缀和可以O(1)完成区间查询,这就是我说这两者相反的第二个原因

差分数组与树状数组的结合

上面我叭叭了半天差分数组不是瞎叭叭,而是要与树状数组进行结合。

差分数组与树状数组特点对比:

————————————————————————————

差分数组:前缀和表示原数,可以用两次单点修改完成区间修改

树状数组:可以快速进行单点修改和查询前缀和

————————————————————————————

对比以上,不难想到,如果对差分数组建立树状数组,就可以对差分数组进行前缀和查询达到单点查询的目的,运用两次单点修改来完成区间修改的目的

例题与程序实现

P3368

这道模板题要求完成区间修改和单点查询

那么利用差分数组与树状数组的结合,就可以这样完成

 1     #include<bits/stdc++.h>
 2     using namespace std;
 3     int n,m,l,r,x;
 4     long long c[500010],k,a;
 5     int lowbit(int x){
 6         return x&(-x);
 7     }
 8     void add(int x,long long y){
 9         while(x<=n){
10             c[x]+=y;
11             x+=lowbit(x);
12         }
13     }
14     long long sum(int x){
15         long long cnt=0;
16         while(x){
17             cnt+=c[x];
18             x-=lowbit(x);
19         }
20         return cnt; 
21     }
22     int main(){
23         scanf("%d%d",&n,&m);
24         long long now=0;
25         for(int i=1;i<=n;i++){
26             scanf("%lld",&a);
27             add(i,a-now);
28             now=a;
29         }
30         while(m--){
31             scanf("%d",&x);
32             if(x==1){
33                 scanf("%d%d%lld",&l,&r,&k);
34                 add(l,k);
35                 add(r+1,-k);
36             }
37             else{
38                 int s;
39                 scanf("%d",&s);
40                 printf("%lld\n",sum(s));
41             }
42         }
43         return 0;
44 }

 

posted @ 2018-11-14 20:25  Noire02  阅读(235)  评论(0编辑  收藏  举报
Live2D