蒙德城即将迎来一年一度的佳酿节,你决定把握这个机会自制苹果酒大赚一笔。
你需要用蒙德城的通用货币摩拉来购买酿造苹果酒所需的苹果。
你每天有x个摩拉的资金,有n家卖苹果的商店,第i家商店每个苹果卖ai个摩拉,由于商人众多,你每天只能从每个商店买到一个苹果。但不好的消息是,距离节日越近,货物就越紧缺,价格也越高:第一天的成本是ai,第二天的成本是ai+1,第三天的成本是ai+2,以此类推。
你要尽你所能的去买更多的苹果,如果你在一天没有花费全部的摩拉,你将不能在之后的日子里继续花费这些摩拉。
最终,每个苹果的成本将超过x,你将无法购买任何一个苹果。那么,到那一刻,你总共能买多少个苹果?Input 有多组测试数据
对于每一个测试数据:
第一行包含一个整数t——测试案例的数量。接下来是t个案例。
每个测试案例的第一行包含两个整数n和x(1≤n≤2⋅10^5;1≤x≤10^9)--商店的数量和你的日常预算。
每个测试案例的第二行包含n个整数a1,a2,...,an(1≤ai≤10^9)--每个商店苹果的费用。
保证n的总和不超过2⋅10^5。Output 对于每个测试案例,打印一个整数--在价格超过你的日常预算之前,你能够购买的苹果的总数量。
末尾有换行
Sample Input 4
3 7
2 1 2
5 9
10 20 30 40 50
1 1
1
2 1000
1 1Sample Output 11
0
1
1500
分析,我的思开始是暴力枚举,直到情况符合,但是超时了,然后想到用前缀和和差分,但是发现还是要判断并且循环,依然超时,然后想到只使用前缀和不用差分,然后在前缀和数组中二分查找第一个小于等于x的数,然后除位置数,就是他能累加的次数,最终ac了,
#include<iostream>
#include <algorithm>
using namespace std;
int main() {
long long t, n, x, ans = 0;
long long s[200005], q[200005];
while (cin >> t) {
while (t--) {
scanf("%lld%lld", &n, &x);
for (int i = 1; i <= n; i++) {
scanf("%lld", &s[i]);
}
sort(s + 1, s + n + 1);
for (int i = 1; i <= n; i++) {
q[i] = q[i - 1] + s[i];
}
if (q[1] > x) {
printf("0\n");
ans = 0;
}
else {
int l = 1, r = n;
while (l < r) {
int mid = (l + r + 1) >> 1;
if (q[mid] <= x) {
l = mid;
} else {
r = mid - 1;
}
}
ans += l;
for (int i = 1; i <= r; i++) {
ans += (x - q[i]) / i;
}
printf("%lld\n", ans);
ans = 0;
}
}
}
}