[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;
}
View Code

 

posted @ 2019-10-16 16:59  ckxkexing  阅读(277)  评论(0编辑  收藏  举报