[CF#592 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 
#include  
#include  
#include   
#include   
#include   
#include    
#include    
#include    
#include    <string>
#include    
#include     
#include     
#include     
#include      
#include       
#include       <set>
#include   
//#include 
//#include 
// #include
// 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<<"-----------------------"<#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 pll;

const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;


template
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

 

你可能感兴趣的:([CF#592 E] [二分答案] Minimizing Difference)