POJ3579 Median(二分答案 + O(N)判定)

本文介绍了一种解决大规模数据集中寻找两个数差值中位数的问题,通过数组排序及二分查找的方法,在O(N)的时间复杂度内完成判断。适用于N<=100000的数据规模。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门
大意:给出N个数,对于存有每两个数的差值的序列求中位数,如果这个序列有偶数个元素,就取中间偏小的作为中位数。

因为N<=100000,所以想要求出每一个差值是不可行的,我们很容易想到二分答案。 在二分答案时我们会进行判定,求出小于等于枚举值的个数,我看其他人的判定似乎都是O(NlogN) 的,我在这里就给出一个O(N)的判定方法。

首先同样将数组排序(我们命名为a数组好了)
我们枚举一个区间[l,r),因为当r增加的时候,要使[l,r)中的数都大于于等于a[r]lrl,O(n)

上代码:

#include <cstdio>
#include <algorithm>
long long n, a[100005];
int main()
{
    long long i, j;
    while(~scanf("%I64d", &n))
    {
        for(i = 1; i <= n; i ++)
            scanf("%I64d", a + i);
        std::sort(a + 1, a + n + 1);
        long long l = 0, r = a[n], mid, m = (n-1)*n/4, num;
        if((n*(n-1)/2)&1) m ++;
        if(n == 1)
        {
            printf("0\n");
            continue;
        }
        while(l < r)
        {
            mid = (l + r) >> 1;
            j = 1;
            num = 0;
            for(i = 2; i <= n; i ++)
            {
                while(a[i] - a[j] > mid)
                    j ++;
                num += (i-j);
            }
            if(num >= m)
                r = mid;
            else l = mid + 1;
        }
        printf("%I64d\n", l);
    }
    return 0;
}

转载于:https://www.cnblogs.com/geng4512/p/5296932.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值