码迷,mamicode.com
首页 > 编程语言 > 详细

总结之---树状数组+逆序对问题。

时间:2014-12-05 21:02:54      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   ar   color   sp   for   on   div   

bubuko.com,布布扣

咳咳,这个图必须要的....

首先,当有一个数组a数量非常大的时候,我们可能改变某个a[i]的值,要求a[n]的和,全部加起来,无疑是要O(n)的时间复杂度。

但是如果n非常大时,O(n)时间复杂度肯定要跪,所以,怎么办的,用神奇的树状数组。

树状数组代码简单,但是非常强大!更令人兴奋的是,它的时间复杂度值需要O(logn)!!!

好了,首先要的东西是把上图的c[n]表示出来,该怎么弄呢,代码如下:

int lowbit(int t)
{
    return t&(-t);
}

这个代码,简单到爆,但是却可以把每一个c[i]的管辖域给找出来!(具体用二进制琢磨)

之后,改变了某个值之后,就要把c[i]更新,当然,用了c[n]之后,数组的数目已经从n变成logn了!

所以,我们用updata函数:

void updata(int l,int k )
{ 
    while(l<=n)
     {
           c[l]+=k;//更新l后的每一个树状数组值 
        l+=lowbit(l);//找上一级 
    }
}

最后,还有一个sum函数:

int sum(int k)
{
       int s=0;
       while(k>0)
     {
           s+=c[k];
           k-=lowbit(k);
      }
    renturn s;
}

 

 

当然 树状数组可以用来求逆序对,这是个非常高效的代码:

for(i=1;i<=n;i++)
{
      updata(c[i],1);
      ans+=sum(n)-sum(c[i]);
}
//别问我为什么,我也不知道...

 

总结之---树状数组+逆序对问题。

标签:style   blog   http   ar   color   sp   for   on   div   

原文地址:http://www.cnblogs.com/ikids/p/4147402.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!