1. 程式人生 > >Interviewe HDU - 3486【線段樹+二分搜尋】

Interviewe HDU - 3486【線段樹+二分搜尋】

題目連線


  題意是這樣說的,有N個人去面試,他們有各自的價值,然後大BOSS又比較的忙,所以想要派出M個小老闆去稽核這幾個面試的小老弟,但是每個小老闆只能夠選出一個人來,就問要達到價值K,需要幾個小老闆選出的最出色的小老弟。

  看到這道題之後,我就想,我們可以用線段樹來找區間最大值,然後二分搜尋去逼近最真實的答案,然後去敲了,就這樣過了,不過好像有點卡的成分在裡面,不知道其他人是用什麼方法過的(畢竟這道題掛出來是掛在圖論下的......)。


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN=200005;
int N, K;
ll a[maxN], pre, tree[maxN<<2];
void buildTree(int rt, int l, int r)
{
    if(l == r)
    {
        tree[rt] = a[l];
        return;
    }
    int mid = (l + r)>>1;
    buildTree(rt<<1, l, mid);
    buildTree(rt<<1|1, mid+1, r);
    tree[rt] = max(tree[rt<<1], tree[rt<<1|1]);
}
ll query(int rt, int l, int r, int ql, int qr)
{
    if(ql<=l && qr>=r) return tree[rt];
    if(l == r) return tree[rt];
    int mid = (l + r)>>1;
    if(ql>mid) return query(rt<<1|1, mid+1, r, ql, qr);
    else if(qr<=mid) return query(rt<<1, l, mid, ql, qr);
    else
    {
        ll ans = query(rt<<1|1, mid+1, r, mid+1, qr);
        ans = max(ans, query(rt<<1, l, mid, ql, mid));
        return ans;
    }
}
int main()
{
    while(scanf("%d%d", &N, &K)!=EOF)
    {
        pre = 0;
        if(N<0 && K<0) break;
        for(int i=1; i<=N; i++)
        {
            scanf("%lld", &a[i]);
            pre += a[i];
        }
        if(pre <= K) { printf("-1\n"); continue; }
        buildTree(1, 1, N);
        int L=1, R=N, mid=0, ans=N;
        while(L <= R)
        {
            mid = (L + R)>>1;
            ll tmp = 0;
            int up = N/mid;
            for(int i=1; i<=mid; i++)
            {
                tmp += query(1, 1, N, (i-1)*up+1, i*up);
            }
            if(tmp > K) { R=mid-1; ans=mid; }
            else L = mid + 1;
        }
        printf("%d\n", ans);
    }
    return 0;
}