树状数组变形:带区间修改的树状数组

原理很简单,利用差分知识做的,只能单点查询,在性能上优于线段树,但没有区间查询功能。

 1 #include<bits/stdc++.h>
 2 #define f(i,a,b) for(int i=a;i<=b;i++)
 3 using namespace std;
 4 
 5 const int N=5e5+5;
 6 int n,q,opt,le,ri,pos,val;
 7 int a[N];
 8 int tree[N];
 9 #define lowbit(x) (x&(-x))
10 void update(int pos,int val){
11     if(pos<=0) return;
12     while(pos<=n){
13         tree[pos]+=val;
14         pos+=lowbit(pos);
15     }
16 }
17 int sum_1_to_pos(int pos){
18     int ans=0;
19     while(pos>0){
20         ans+=tree[pos];
21         pos-=lowbit(pos);
22     }
23     return ans;
24 }
25 #define query(x,y) (sum_1_to_pos(y)-sum_1_to_pos(x-1))
26 
27 int main(){
28     scanf("%d%d",&n,&q);
29     scanf("%d",&a[1]);
30     f(i,2,n) scanf("%d",&a[i]),update(i-1,a[i]-a[i-1]);
31     f(i,1,q){
32         scanf("%d",&opt);
33         if(opt==1){
34             scanf("%d%d%d",&le,&ri,&val);
35             update(le-1,val);
36             update(ri,-val);
37             if(le==1) a[1]+=val;
38             //cout<<"array is:\n";
39             //f(i,1,n) cout<<i<<" : "<<a[1]+query(1,i-1)<<endl;
40         }
41         else{
42             scanf("%d",&pos);
43             printf("%d\n",a[1]+query(1,pos-1));
44         }
45     }
46 } 

 

posted @ 2020-02-07 11:38  Lovaer  阅读(165)  评论(0编辑  收藏  举报