P3374 【模板】树状数组 1
---------------------------------------------------
-------------------------------------------------------
树状数组是个很有用的数据结构,当然,有许多时候我们也可以用线段树代替他。
不过线段树比树状数组难得多,所以应该是用树状数组代替线段树才对。
比如说看看这个:[洛谷日报第22期]可以代替线段树的树状数组?
------------------------------------------------------
树状数组是一种基于二进制思想实现的数据结构,要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值;经过简单修改可以在log(n)的复杂度下进行范围修改,但是这时只能查询其中一个元素的值(如果加入多个辅助数组则可以实现区间修改与区间查询)。然而在洛谷上,这两部分是分开的。这个模板一实现的是单点修改和区间之和。
还有,这和前缀和有关系。
-----------------------------------------------------
特别的,
不知道前缀和/差分?请看这位大佬
------------------------------------------------------
由于树状数组涉及到了深奥的二进制,理解原理请看这篇blog
-------------------------------------------------------
以下为代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 3 using namespace std; 4 int f,x,y; 5 int n,m; 6 int now; 7 int t[500001]; 8 int lowbit(int x){ 9 return x& -x; 10 } 11 void add(int p,int x){ 12 while(p<=n){ 13 t[p]+=x; 14 p+=lowbit(p); 15 } 16 } 17 18 int sum(int x){ 19 int ans=0; 20 while(x){ 21 ans+=t[x]; 22 x-=lowbit(x); 23 } 24 return ans; 25 } 26 27 int main(){ 28 cin>>n>>m; 29 for(int i=1;i<=n;++i){ 30 cin>>now; 31 add(i,now); 32 } 33 for(int i=1;i<=m;++i){ 34 cin>>f>>x>>y; 35 if(f==1){ 36 add(x,y); 37 } 38 else 39 { 40 cout<<sum(y)-sum(x-1)<<endl;; 41 } 42 43 } 44 45 return 0; 46 }