逆序对 树状数组学习记录(2017.10.25)
这个问题很有意思,花了很长时间才弄明白,在此总结一下整个过程。
目的:用树状数组求逆序对的个数问题。
一.概念介绍
逆序对:对于一个给定的1~n的排列a0,a1,......,an-1 ,满足i<j,ai>aj 的(i,j)的数对即为逆序对。
树状数组(Binary Indexed tree,BIT):
- 功能:给定一个初始值全为0的数列a1,a2,……,an ,给定i,计算a1+a2+……+ai
给定i和x,执行ai+=x,这俩种操作都需要O(logn)的时间复杂度。
- 结构:如图1
图一
(3)这个结构是怎样产生的呢?
它是由线段树(如下图2满二叉树,根点维护整个区间,每个节点维护的是父节点的区间二等分后的其中的一个子区间),去掉每个节点的右子节点。
图2
- 通项规律
由上图可以知道
C[1]=A[1];
C[2]=A[1]+A[2];
C[3]=A[3];
C[4]=A[1]+A[2]+A[3]+A[4];
C[5]=A[5];
C[6]=A[5]+A[6];
C[7]=A[7];
C[8]=A[1]+A[2]+A[3]+A[4]+A[5]+A[6]+A[7]+A[8];
让我们对比每个节点对应的区间长度和节点编号的二进制表示。以1结尾的1,3,5,7的长度是1,最后有1个0的2,6的长度是2,最后有2个0的4的长度是4······由此编号的二进制就能够和区间非常容易地对应起来。
因此我们可以得出C[i]=A[i-2^k+1]+A[i-2^k+2]+......A[i]; &