[CF1244 E] [二分答案] Minimizing Difference
链接:http://codeforces.com/contest/1244/problem/E
题意:
给定包含$n$个数的数组,你可以执行最多k次操作,使得数组的一个数加1或者减1。
问合理的操作,使得数组中最大的数和最小的数差值最小。
思路:
二分答案,重点是检查的时候需要跑两遍。
// #pragma GCC optimize(2) // #pragma GCC optimize(3) // #pragma GCC optimize(4) #include <algorithm> #include <iterator> #include <iostream> #include <cstring> #include <cstdlib> #include <iomanip> #include <bitset> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <stack> #include <cmath> #include <queue> #include <list> #include <map> #include <set> #include <cassert> //#include <unordered_set> //#include <unordered_map> // #include<bits/extc++.h> // using namespace __gnu_pbds; using namespace std; #define pb push_back #define fi first #define se second #define debug(x) cerr << #x << " := " << x << endl; #define bug cerr << "-----------------------" << endl; #define FOR(a, b, c) for (int a = b; a <= c; ++a) typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; const int inf = 0x3f3f3f3f; const ll inff = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; template <typename T> inline T read(T &x) { x = 0; int f = 0; char ch = getchar(); while (ch < '0' || ch > '9') f |= (ch == '-'), ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x = f ? -x : x; } /**********showtime************/ const int maxn = 1e5 + 9; int a[maxn]; ll sum[maxn]; int n; ll k; bool check(int dif) { int le = 1; for (int i = 1; i <= n; i++) { while (le < i && a[i] - a[le] > dif) le++; ll zuo = 1ll * (le - 1) * (a[i] - dif) - sum[le - 1]; ll you = sum[n] - sum[i] - 1ll * (n - i) * a[i]; if (zuo + you <= k) return true; } int ri = 1; for (int i = 1; i <= n; i++) { while (ri + 1 <= n && a[ri + 1] - a[i] <= dif) ri++; ll zuo = 1ll * (i - 1) * a[i] - sum[i - 1]; ll you = sum[n] - sum[ri] - 1ll * (n - ri) * (a[i] + dif); if (zuo + you <= k) return true; } return false; } int main() { scanf("%d%lld", &n, &k); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); } sort(a + 1, a + 1 + n); for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + a[i]; int le = 0, ri = mod; int res; while (le <= ri) { int mid = (le + ri) >> 1; if (check(mid)) res = mid, ri = mid - 1; else le = mid + 1; } printf("%d\n", res); return 0; }
skr