Loading

POJ-3579 Median

Median

给n组数,将其两两之差列为新的数列,求这个数列的中位数

二分套二分

很容易想到是二分答案,查看有多少个数小于等于这个答案

抽象的地方在于查询有多少个差小于等于当前的差,通过二分\(a[i]+x\)在原数组的位置来判断,有多少个数 \(y \ge a[i] + x\),从而判断以\(pair(a[i], y)\)的差小于当前的差,然后\(n\)跑下来就行

时间复杂度是\(o(logn*nlogn)\)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
ll num[maxn], n;

ll query(ll val)
{
    ll ans = 0;
    for(int i=0; i<n; i++)
    {
        ll way = upper_bound(num, num + n, num[i] + val) - num;
        ans += way - i - 1;
    }
    return ans;
}

int main()
{
    
    while(scanf("%lld", &n) != EOF)
    {
        for(int i=0; i<n; i++)
            scanf("%d", &num[i]);
        sort(num, num + n);
        ll l = 0, r = num[n-1];
        ll sum = (n * (n - 1) / 2 + 1) / 2;
        while(l < r)
        {
            ll mid = l + r >> 1;
            if(query(mid) >= sum)
                r = mid;
            else
                l = mid + 1;
        }
        printf("%lld\n", l);
    }
    return 0;
}
posted @ 2022-04-25 18:18  dgsvygd  阅读(21)  评论(0编辑  收藏  举报