hdu6383 p1m2(二分答案)

Posted whisperlzw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu6383 p1m2(二分答案)相关的知识,希望对你有一定的参考价值。

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\n", mid);
    
    return 0;

以上是关于hdu6383 p1m2(二分答案)的主要内容,如果未能解决你的问题,请参考以下文章

hdu4768二分答案

hdu4190 二分答案

hdu1969---Pie

[hdu2298] 物理推导+二分答案

Maximum Shortest Distance 最大团 二分答案 HDU 3585

hdu3586 树形dp+二分答案