一、差分数组建数组原理:
树状数组(区间更新)//差分数组
令树状数组建树为
(设a是原始数组,tree是树状数组)
原理:
区间更新若要将区间[L,R]内每一点的值增加h
即a[L]+=h;a[L+1]+=h;a[R]+=h;
- 区间[1,L-1]的a值不变,所以tree的对应值也不变
- 因为a[L]+=h; a[L-1]不变
tree[L]=a[L]-a[L-1];
所以:tree[L]增大h - 在i∈[L+1,R]内
tree[i]=a[i]-a[i-1];
a[i]和a[i-1]都加了h,相减都减掉了
所以:tree[i]不变 - 对于tree[R+1]=a[R+1]-a[R];
a[R+1]不变,a[R]增大了h
所以tree[R+1]减少了h
综上:区间更新时,只需要更新tree的两个点
二、多种求和方式转化:
求和:
对于tree数组的建立方式,可知
a[i]=tree[1]+tree[2]+……+tree[i];
- 若是单点查询,即求tree的前缀和即可
- 若是区间[1,x]查询
sum(x)=a[1] +a[2] +a[3] +…+a[x]
=tree[1]+(tree[1]+tree[2])+ (tree[1]+tree[2]+tree[3])+…+(tree[1]+…+tree[x])
=x*tree[1]+(x-1)*tree[2]+…+2*tree[x-1]+tree[x](因为每次都是变的,所以这样仍不能求)
=x*(tree[1]+…+tree[x])-(tree[2]+2*tree[3]+…+(x-1)tree[x])
=x*
要求上式,可以建2个树状数组,A[]和B[]
sum=x*sum(A[x])-sum(B[x]);
(区间更新时)数组A是正常的添加值,数组B的添加值要乘上前面的系数(i-1)(结合树状数组求和方式再好好想想)
3.区间[L,R]的和的查询
- ans=a[L]+a[L+1]+…+a[R] (这种简单)
=sum(R)-sum(L) - 令len=R-L+1;
若求公式ans=len*a[L]+(len-1)*a[L+1]+…+a[R]
则同上的转化方式 得:
(自己转化一下就可以了,树状数组不变)
对于区间【L,R】的查询(3)
<1>例题见https://blog.youkuaiyun.com/qq_37868325/article/details/81123044的J题
<2>的例题见https://blog.youkuaiyun.com/qq_37868325/article/details/82561477的H题。