Codeforces Round #577 (Div. 2) 1201C Maximum Median 前缀和/二分答案

解法一:前缀和+模拟

求增加k之后的最大中位数,必定是在后半段区间进行操作。我们可以很容易想到,先将中间数增大,然后再对后半段区间进行操作使中间数还是中位数,而使an/2还是中位数的话,后面的数仍是升序。
a(n/2)增加到a(n/2)+1,总共需要加(a(n/2)+1-a(n/2)) × \times 1
a(n/2)增加到a(n/2)+2,总共需要加(a(n/2)+1-a(n/2)) × \times 1 + (a(n/2)+2-a(n/2)+1) × \times 2
a(n/2)增加到a(n/2)+3,(a(n/2)+1-a(n/2)) × \times 1 + (a(n/2)+2-a(n/2)+1) × \times 2 + (a(n/2)+3-a(n/2)+2 × \times 3

依次类推,这就是一个前缀和表达式。因此我们只需要找到k所处的范围,并进行不能完全增到到a(n/2)+?的处理。时间复杂度O(n)

 #include <cstdio>
#include <algorithm>
#include <iostream>
#include <cmath>
#define _for(i, a, b) for (int i = (a); i < (b); ++i)
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
const int MAXN = 2e5 + 10;
long long a[MAXN], b[MAXN];
using namespace std;
typedef long long ll;
int n,k;
int main()
{
	scanf("%d%d", &n, &k);
	_for (i, 0, n) scanf("%d", &a[i]);
	sort(a, a+n);
	int cnt = 0;
	_for (i, n/2+1, n) b[++cnt] = a[i] - a[i - 1];//计算前缀和
    int ans = 0;
    //开始模拟
    _rep (i, 1, cnt) 
    if (k >= ll(b[i] * i)) {k -= b[i]*i; ans += b[i];}//如果k满足增加到a[(n/2)+i]所需要的花费,那么中间数则可以增加b[i]
    else {ans += k / i; k = 0;break;}//不能满足增加到a[(n/2)+i]所需要的花费,从最右端开始一个一个增加,中间数只能加最少的
    if (k)//如果处理完,k还有剩余。那么说明中间数已经增加到a[n-1]
    {
        ans += k / (n/2 + 1);
    }
    printf("%d\n", a[n/2] + ans);
}

解法二:二分答案

在这里插入图片描述
二分查找最大中位数,模拟增加量与k的关系,判断是否最大。

#include <bits/stdc++.h>
#define _for(i, a, b) for (int i = (a); i < (b); ++i)
using namespace std;
typedef long long ll;
ll n, k;
ll x;
vector<ll> a;
//模拟x为中位数需要增加多少moves
bool check(ll x)
{
    ll moves = 0;
    _for (i, n / 2, n)
    {
        if (x - a[i] > 0)  moves += x - a[i];
        if (moves > k) return false;
    }
    if (moves <= k) return true;
    else return false;
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin >> n >> k;
    _for (i, 0, n) {cin >> x; a.push_back(x);}
    sort(a.begin(), a.end());
    ll l = 1, r = 2e10, mid;
    //查找满足条件的最大值
    while (l != r)
    {
        mid = (l + r + 1) >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    cout << l;
}

发布了51 篇原创文章 · 获赞 19 · 访问量 8299

猜你喜欢

转载自blog.csdn.net/WxqHUT/article/details/98482767