树状数组+二分
考虑一个简单的问题,维护一个数组,支持每次修改一个数的值,保证每时每刻每个数都为非负数。每次查询求第一个前缀和≥k的下标。
对于修改,可以用树状数组、线段树等数据结构维护。
二分查找
可以在[l,r]的范围上二分答案,mid=⌊2l+r⌋,验证mid的前缀和是否大于k,并调整mid。时间复杂度O(log22n)
如果用线段树来做,维护区间和,每次判断x在左儿子还是右儿子中,若在右儿子中,x变为x减去左儿子的区间和。时间复杂度O(log2n)
树状数组上二分
由于树状数组的特性,每个节点维护的区间长度均为2的整数次幂,因此考虑使查询区间和时区间长度为2的整数次幂且有节点维护。
设现在维护的树状数组s,二分查找的区间为(l,r]的区间,l位置的前缀和为lsum。l初值为0,r二分初值为二分上限。
当r−l的值为2的整数次幂时,mid=⌊2l+r⌋,否则mid=l加(0,r−l)中最大的2的整数次幂。
当k>s[mid]+lsum时,l=mid,lsum=lsum+s[mid],否则r=mid。
这样一直迭代,直到l=r−1时退出。

这张图中k=11,二分上界为13。
补充说明:http://codeforces.com/blog/entry/71992
时间复杂度O(log2n)。
此算法优点:速度快
局限性:只能处理从下标一开始的前缀问题,不如线段树强大。