树状数组

树状数组复习。

一个一维数组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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值