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;
}

原文地址:https://www.cnblogs.com/whisperlzw/p/11211701.html

时间: 2024-10-08 21:38:50

hdu6383 p1m2(二分答案)的相关文章

百度之星2018初赛Bt4 P1m2(二分答案)

src:http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=826&pid=1004 可以用某值来判断是否满足题意时 可以用二分答案的方法! 代码: #include<bits/stdc++.h> using namespace std; #define per(i,a,b) for(int i=a;i <= b;i++) #define Max(a,b) a=max(a,b) #define Min(

[二分答案]p1m2

Problem Description 度度熊很喜欢数组!! 我们称一个整数数组为稳定的,若且唯若其同时符合以下两个条件: 1. 数组里面的元素都是非负整数.2. 数组里面最大的元素跟最小的元素的差值不超过 1 . 举例而言,[1,2,1,2] 是稳定的,而 [−1,0,−1] 跟 [1,2,3] 都不是. 现在,定义一个在整数数组进行的操作: * 选择数组中两个不同的元素 a 以及 b ,将 a 减去 2 ,以及将 b 加上 1 . 举例而言,[1,2,3] 经过一次操作后,有可能变为 [−1

Codeforces 772A Voltage Keepsake - 二分答案

You have n devices that you want to use simultaneously. The i-th device uses ai units of power per second. This usage is continuous. That is, in λ seconds, the device will use λ·ai units of power. The i-th device currently has bi units of power store

HDU3081Marriage Match II(二分答案+并查集+最大流SAP)经典

Marriage Match II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2507    Accepted Submission(s): 856 Problem Description Presumably, you all have known the question of stable marriage match. A

Codeforce 371C Hamburgers (二分答案)

题目链接 Hamburgers 二分答案,贪心判断即可. 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define REP(i,n) for(int i(0); i < (n); ++i) 6 #define LL long long 7 8 char str[1010]; 9 LL len; 10 LL b, c, s, nb, nc, ns, pb, pc, ps; 11 LL money; 12 13 bool

POJ 3080 Blue Jeans(后缀数组+二分答案)

[题目链接] http://poj.org/problem?id=3080 [题目大意] 求k个串的最长公共子串,如果存在多个则输出字典序最小,如果长度小于3则判断查找失败. [题解] 将所有字符串通过拼接符拼成一个串,做一遍后缀数组,二分答案,对于二分所得值,将h数组大于这个值的相邻元素分为一组,判断组内元素是否覆盖全字典,是则答案成立,对于答案扫描sa,输出第一个扫描到的子串即可. [代码] #include <cstdio> #include <cstring> #inclu

【二分答案+智障的字符串hash】BZOJ2946-[Poi2000]公共串(Ranklist倒一达成!!!!!)【含hash知识点】

[题目大意] 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. [字符串hash的小笔记] hash[i]=(hash[i-1]*p+idx(s[i]))%mod,idx为映射值,一般a..z映射1..26: 习惯上,p取一个6到8位的素数即可,mod一般取大素数 1e9+7(1000000007)或1e9+9(1000000009). hash[i]=(hash[i-1]*p+idx(s[i]))%mod 表示第 i 个前缀的hash值,是一个hash的前缀和,那么,要求S[l…r]

IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2) 二分答案 + 网络流

这道题的意思是给你一个有向图, 每条边上有一个最大载重量, 现在有x头牛要从顶点1走向顶点n, 每头牛要载的重量都是一样的, 问你最多能载多少的重量? 可以二分答案, 算出每头牛的载重, 然后修改边权, 跑一次最大流即可判断当前答案是否正确, 二分答案即可, 注意由于原始边权/每头牛的载重量可能会很大, 因此我们在修改边权时应该注意这一点,将边权的最大值控制在1000000之内, 防止溢出, 代码如下: #include <bits/stdc++.h> using namespace std;

BZOJ 1305 CQOI2009 dance跳舞 二分答案+最大流

题目大意:给定n个男生和n个女生,一些互相喜欢而一些不.举行几次舞会,每次舞会要配成n对.不能有同样的组合出现.每一个人仅仅能与不喜欢的人跳k次舞,求最多举行几次舞会 将一个人拆成两个点.点1向点2连一条流量为k的边.两个人若互相喜欢则点1之间连边,不喜欢则点2之间连边 对于每个要验证的x值 将每个人的点1向源或汇连一条流量为x的边 然后二分答案跑最大流就可以 #include<cstdio> #include<cstring> #include<iostream> #