p1m2
解题思路
因为x都是非负数,且每一次操作其实就是把总和减少了1,所以可以得出最后都可以到达稳定。最后稳定的数的下界是0,最大也不会超过其初始数的最大值,所以可以用二分答案来求解。每次二分,我们统计要到达出来的二分值,每个数进行上升操作的次数总和以及下降次数的总和。如果上升次数大于下降次数,说明这个答案偏大了则r=mid-1,如果上升次数小于下降次数,由于答案是要求稳定后的最小值,而我们计算是使所有数都变得一样,所以下降次数其实是可以大于上升次数的,所以此时和相等时一样,都是使l=mid;
代码如下
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
inline int read(){
int res = 0, w = 0; char ch = 0;
while(!isdigit(ch)){
w |= ch == '-', ch = getchar();
}
while(isdigit(ch)){
res = (res << 3) + (res << 1) + (ch ^ 48);
ch = getchar();
}
return w ? -res : res;
}
const int N = 300005;
int x[N];
int n;
bool work(int k)
{
ll l = 0, r = 0;
for(int i = 1; i <= n; i ++){
if(x[i] < k)
r += k - x[i];
else {
l += (x[i] - k + 1) / 2;
r += (x[i] - k) % 2;
}
}
return l >= r;
}
int main()
{
int t;
cin >> t;
while(t --){
n = read();
int l = 0, r = 0;
for(int i = 1; i <= n; i ++)
x[i] = read(), r = max(r, x[i]);
int mid = (l + r + 1) / 2;
while(l < r){
if(work(mid))
l = mid;
else
r = mid - 1;
mid = (l + r + 1) / 2;
}
printf("%d
", mid);
}
return 0;
}