树状数组复习。
一个一维数组tree[]
其中tree[i]表示
[i-(i&(-i))+1,i]这个区间内a数组元素的和
想求a[1]~a[15]的值?
15=(1111)2
tree[15]=sum[15,15]
tree[14]=sum[13,14]
tree[12]=sum[9,12]
tree[8]=sum[1,8]
sum[1,15]=tree[8]+tree[12]+tree[14]+tree[15]
执行的次数和二进制中‘1’的位数有关
•read(intpos) 求 sum[1,pos]的答案
•update(intpos,int v) 把a[pos]加上v
•如果要查询sum[l,r]呢?
–read(r)-read(l-1)
int read(int p)
{
int ans=0;
while(p>0)
{
ans+=tree[p];
p-=p&-p;
}
return ans;
}
void update(int pos,int val)
{
while(pos<maxn) //maxn为总长度
{
tree[pos]+=val;
pos+=pos&-pos;
}
}
一个特殊的应用,找整个序列中第k个小的数
intfind_Kth(int k,int N)
{
int now=0;
for (int i=20;i>=0;i--)
{
now|=(1<<i);
if (now>N || tree[now]>=k) now^=(1<<i);
else k-=tree[now];
}
return now+1;
}