NYOJ 2354-分班级(二分)

来源:互联网 发布:苹果mac os x系统下载 编辑:程序博客网 时间:2024/05/21 16:59


题解:一道简单题,之前一直想歪了,set,优先队列都试过,简直年轻,其实直接两次二分就行了,一次二分最小值,一次二分最大值。(注意上下界)

#include<set>  #include<map>         #include<stack>                #include<queue>                #include<vector>        #include<string>      #include<math.h>       #include<stdio.h>                #include<iostream>                #include<string.h>                #include<stdlib.h>        #include<algorithm>       #include<functional>        using namespace std;typedef long long ll;#define inf 1000000000           #define mod 1000000007                 #define maxn  500005     #define PI 3.1415926  #define lowbit(x) (x&-x)     #define eps 1e-9   ll a[maxn], n, k;bool check1(ll x){int i;ll res = 0;for (i = 1;i <= n;i++)if (a[i] < x)res += x - a[i];if (res <= k)return 1;return 0;}bool check2(ll x){int i;ll res = 0;for (i = 1;i <= n;i++)if (a[i] > x)res += a[i] - x;if (res <= k)return 1;return 0;}int main(void){ll  i, j, ans1, ans2, tmp, l, r, sum, mid;while (scanf("%lld%lld", &n, &k) != EOF){ans1 = 0;sum = 0;ans2 = 0;for (i = 1;i <= n;i++) scanf("%lld", &a[i]), sum += a[i];ll mx = sum / n;l = 1, r = mx;while (l <= r){mid = (l + r) / 2;if (check1(mid)){ans1 = mid;l = mid + 1;}elser = mid - 1;}if (sum%n) mx++;l = mx;r = sum;while (l <= r){mid = (l + r) / 2;if (check2(mid)){ans2 = mid;r = mid - 1;}elsel = mid + 1;}printf("%lld\n", ans2 - ans1);}return 0;}