题目链接:http://codeforces.com/contest/727/problem/F
题目大意:有n个问题,每个问题有一个价值ai,一开始的心情值为q,每当读到一个问题时,心情值将会加上该问题的价值。问题只能按顺序读。有m个询问,求当q=bi时,至少要删去多少个问题才能使得在任何时候心情值都>=0。
数据范围:1 ≤ n ≤ 750, 1 ≤ m ≤ 200 000, - 10^9 ≤ ai ≤ 10^9, 0 ≤ bi ≤ 10^15
题解:显然我们不能等到询问的时候再处理,这样时间复杂度太大承受不下。所以我们可以先预处理出ans[i]表示如果要留下 i 个问题那么一开始的心情值至少要为多少,显然ans是非递减的序列,我们可以在询问的时候二分即可找出答案。处理出ans有两种方法:
1.二分+贪心
虽然复杂度有点危险但是因为本蒟蒻的贪心太差于是还是写了下来(反正cf评测机快hhhh)。
首先我们可以知道,如果ans[i]=x时满足条件,那么ans[i]=x+1时也是满足条件的(废话),于是我们还是可以二分。对于 i ,我们二分出mid,判断当q=mid时,能否留下 i 个问题。这里的判定我们可以用贪心。一开始心情值为mid,每当遇到一个新的问题 j 时,把心情值加上a[ j ],然后把a[j]存进一个小根堆里,如果当前的心情值小于0,就把心情值减去堆里最小的数(这必然是个负数且小于等于a[ j ]),然后把这个数移出堆。如果最后被移出堆的数<=n-i 就说明这个mid符合条件。询问的时候在ans上查找就可以了。