第k大区间和问题的树状数组实现

本文介绍了如何使用树状数组解决寻找给定整数序列中第k大区间和的问题,通过二分查找和树状数组实现,避免了平衡树的复杂性,减少了代码量和常数时间,保持了良好的效率。
摘要由CSDN通过智能技术生成

问题描述:

    给定一个整数序列a[1..N],定义sum[i][j]=a[i]+a[i+l]+……+a[j],将所有的sum[i][j]从小到大排序(其中i,j满足1<=i<=j<=N),得到一个长为N*(N+1)/2的序列,求该序列中的第k个元素。

输入格式(ktm.in)

    第一行有两个整数N,k,其中0<N<=20000,1<=k<=N*(N+1)/2,数据保证任何一个sum[i][j]的绝对值不超过2^30。

    接下来N行每行一个整数。顺序给出序列a的元素。

输出格式(kth.out)                       

   sum序列中的第k个元素

题解:

      这道题据说是noip难度的,如果noip真的考这个我就可以直接退役了.

      我讲这道题主要是想讲如何用树状数组来代替平衡树的部分功能,从而节省代码量.

      算法是很显然的:首先二分答案.假设答案为k,我们求出所有sum中小于k的个数就行了.算法的瓶颈在于什么找到所有sum中有多少小于k.

      先讲讲平衡树的做法:预处理一个s数组,s[i]表示sum[0,i].依次加入s[i],统计s1~s[i-1]中大于s[i]-k的个数即可.利用一个平衡树就可以很简单的做到这些操作.

      然而,平衡树不仅代码量较大且常数很高,所以我们考虑利用其他数据结构来实现这一功能.

      这个数据结构要支持两种操作:加入:加入一个元素;查找:查找所有元素中比k小的元素个数.

      这个东西貌似只有平衡树之类的高级数据结构能做,但是,我们可以只用一个

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值