初见安~这里是传送门:CF #577 Div2 C Maximum Median
Description
You are given an array aa of nn integers, where nn is odd. You can make the following operation with it:
- Choose one of the elements of the array (for example aiai) and increase it by 11 (that is, replace it with ai+1ai+1).
You want to make the median of the array the largest possible using at most kk operations.
The median of the odd-sized array is the middle element after the array is sorted in non-decreasing order. For example, the median of the array [1,5,2,3,5][1,5,2,3,5] is 33.
Input
The first line contains two integers nn and kk (1≤n≤2⋅1051≤n≤2⋅105, nn is odd, 1≤k≤1091≤k≤109) — the number of elements in the array and the largest number of operations you can make.
The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109).
Output
Print a single integer — the maximum possible median after the operations.
Examples
input
3 2
1 3 5
output
5
input
5 5
1 2 1 1 1
output
3
input
7 7
4 1 2 4 3 4 4
output
5
Note
In the first example, you can increase the second element twice. Than array will be [1,5,5][1,5,5] and it's median is 55.
In the second example, it is optimal to increase the second number and than increase third and fifth. This way the answer is 33.
In the third example, you can make four operations: increase first, fourth, sixth, seventh element. This way the array will be [5,1,2,5,3,5,5][5,1,2,5,3,5,5] and the median will be 55.
Sol
要记得开long long……我记住了……
没开long long的代码被后期加上的数据卡掉了……掉了一千多名……【暴风哭泣】
这个题吧——可以进行k次让任意一个数+1,求最大的中位数。因为是只有+1的操作,所以只存在中位数和它前面的原本比他大数进行交换位置。所以我们只考虑 这个范围内的数就行了。后期就可以用于一种类似于填坑的思路来做。
假设我们处理到了范围 。
首先肯定是希望数都尽量大,并且保证我们的中位数一直都是中位。如果是这样的一个样例:
5 8
1 2 3 4 10
3和4,3可以和4齐平,用1次操作变成;剩余操作次数9次;
而后两个4一起看,后一个数是10,但是要齐平就需要12次操作,所以我们就可以在10以内让这两个数尽量大,也就是再用8次操作变成:,最大的中位数就是8了。还剩一次操作是没有意义的。
所以就可以得出结论:
如果可以和下一个数齐平,那就一起填上去;如果不够了,那就一起尽量变大,并停止操作就可以了。
上代码——还是很简单的一个题……就是在计算填坑的消耗的时候可能会爆int需要开longlong……【当然不需要像我这样开的丧心病狂】
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define maxn 200005
#define int long long//丧心病狂。
using namespace std;
int read() {
int x = 0, f = 1, ch = getchar();
while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
while(isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar();
return x * f;
}
int n, m, a[maxn];
signed main() {
n = read(), m = read();
for(int i = 1; i <= n; i++) a[i] = read();
sort(a + 1, a + 1 + n);
int cnt = 1, ans = a[n / 2 + 1], now = n / 2 + 1;//先取中间位置
while(m) {
if(now < n && m >= 1ll * cnt * (a[now + 1] - a[now])) {//如果没到最后一个,可以填上去
m -= 1ll * cnt * (a[now + 1] - a[now]); //填
cnt++, now++; ans = a[now];//往后走一个
}
else {ans += m / cnt; break;}//否则就可以结束了。不管是到了最后一个还是不够填了
}
printf("%lld\n", ans);
return 0;
}
迎评:)
——End——