arc144B 最大化加减操作后的最小值
给定数组A[i],以及两个数a和b,其中a<=b,每次可以任选一对下标(i,j),让A[i]增加a,同时A[j]减少b,操作次数不限。求能得到的min(A[i])的最大值。
由于每次加得少、减得多,总和必收敛,因此解一定存在,可以二分答案,条件是增加的次数不超过减少的次数。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a; i<=b; i++)
#define per(i,a,b) for(int i=b; i>=a; i--)
const int N = 300005;
int n, a, b, A[N];
int check(int x) {
int u = 0, v = 0;
rep(i,1,n) {
if (A[i] < x) {
u += (x-A[i]+a-1) / a;
} else {
v += (A[i]-x) / b;
}
}
return u <= v;
}
void solve() {
cin >> n >> a >> b;
rep(i,1,n) cin >> A[i];
int lo = 0, hi = 1E10, mid;
while (lo + 1 < hi) {
mid = (lo + hi) / 2;
if (check(mid)) {
lo = mid;
} else {
hi = mid;
}
}
cout << lo << "\n";
}
signed main() {
cin.tie(0)->sync_with_stdio(0);
int t = 1;
while (t--) solve();
return 0;
}