P3368 【模板】树状数组 2
--------------------------------------------
看一下模板一?请点击
--------------------------------------------
好,这道题让我们实现区间修改和单点查询。但是根据:1中我们可以发现,树状数组的操作只有修改单点和区间求和,那该怎么实现?
我们不可能强行加上这些功能,就需要进行改造。最简单的方法就是改变数组。
--------------------------------------------
有一个数组,我们只要改变其中两个点,就可以实现改变区间。我们只要加上一段区间,就可以求出一个点的和。这个数组就是——差分。
没错,我们在实现树状数组时,我们记录的数组不是它的值,而是差分!!!
其余的就都一样了。
不知道前缀和/差分?请看这位大佬
--------------------------------------------
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int t[500001]; 5 int n,m; 6 int now; 7 int f,x,y; 8 int last; 9 int v; 10 int lowbit(int x){ 11 return x &-x; 12 } 13 void add(int p,int x){ 14 while(p<=n){ 15 t[p]+=x; 16 p+=lowbit(p); 17 } 18 } 19 int sum(int n){ 20 int ans=0; 21 while(n){ 22 ans+=t[n]; 23 n-=lowbit(n); 24 } 25 return ans; 26 } 27 int main(){ 28 scanf("%d%d",&n,&m); 29 for(int i=1;i<=n;++i){ 30 scanf("%d",&now); 31 add(i,now-last); 32 last=now; 33 } 34 for(int i=1;i<=m;++i){ 35 cin>>f; 36 { 37 if(f==1) 38 { 39 // scanf("%d",&v); 40 cin>>x>>y>>v; 41 add(x,v); 42 add(y+1,-v); 43 } 44 if(f==2){ 45 cin>>x; 46 cout<<sum(x)<<endl; 47 48 49 } 50 } 51 } 52 return 0; 53 }