目錄
Description
有 \(n\) 個騎士,都有一個能力值 \(a[i]\), 有 \(m\) 個怪物,怪物有兩個屬性 \(x, y\) ,你可以花費 \(1\) 個金幣使得任意一個騎士的能力值 \(+1\),最后派出一個騎士,滿足這個騎士 \(a[i]>=x\),其余騎士的能力值之和 \(sum>=y\),求最小花費
State
\(1<=n,m<=2*10^5\)
\(1<=a[i]<=10^{12}\)
\(1<=x<=10^{12},1<=y<=10^{18}\)
Input
4
3 6 2 3
5
3 12
7 9
4 14
1 10
8 7
Output
1
2
4
0
2
Solution
題目給我的感覺就是有兩個極端,一個是讓能力值最小的英雄出去,但是他消耗的金幣可能會很多;另一個是讓能力值最大的出去,但是剩下的花費金幣會很多,所以大膽的猜測是一個凹函數,套三分的模板
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 5;
int n, m, _, k;
ll a[N];
ll x, y, sum;
ll C(int mid)
{
ll res = sum - a[mid];
ll ans = x - a[mid];
if(ans < 0) ans = 0;
res = y - res;
if(res < 0) res = 0;
return ans + res;
}
signed main()
{
while(~ scanf("%d", &n)){
for(int i = 1; i <= n; i ++){
scanf("%lld", a + i);
sum += a[i];
}
sort(a + 1, a + 1 + n);
scanf("%d", &m);
while(m --> 0){
cin >> x >> y;
int l = 1, r = n;
ll ans = 6e18;
while(r >= l){
int midl = l + (r - l) / 3;
int midr = r - (r - l) / 3;
if(C(midl) < C(midr)){
r = midr - 1;
}
else{
l = midl + 1;
}
ans = min(ans, min(C(l), C(r)));
}
printf("%lld\n", ans);
}
}
return 0;
}