[TJOI2013] 奖学金

按 a 排序,暴力用堆维护两侧预处理, 然后枚举中位数即可

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N  = 1000005;

struct item {
    int a,b;
    bool operator < (const item &x) {
        return a < x.a;
    }
} I[N];

int n,c,f,a[N],b[N],p[N],q[N];

signed main() {
    ios::sync_with_stdio(false);
    cin>>n>>c>>f;
    for(int i=1;i<=c;i++) cin>>I[i].a>>I[i].b;
    sort(I+1,I+c+1);
    for(int i=1;i<=c;i++) a[i]=I[i].a, b[i]=I[i].b;
    priority_queue <int> qu;
    int sum=0;
    for(int i=1;i<=n/2;i++) qu.push(b[i]),sum+=b[i];
    for(int i=n/2+1;i<=c;i++) {
        p[i]=sum;
        qu.push(b[i]);
        sum+=b[i];
        sum-=qu.top();
        qu.pop();
    }
    while(qu.size()) qu.pop();
    sum=0;
    reverse(b+1,b+c+1);
    for(int i=1;i<=n/2;i++) qu.push(b[i]),sum+=b[i];
    for(int i=n/2+1;i<=c;i++) {
        q[i]=sum;
        qu.push(b[i]);
        sum+=b[i];
        sum-=qu.top();
        qu.pop();
    }
    reverse(b+1,b+c+1);
    reverse(q+1,q+c+1);
    //for(int i=1;i<=c;i++) cout<<b[i]<<" "<<p[i]<<" "<<q[i]<<endl;
    int ans=0;
    for(int i=n/2+1;i<=c-(n/2);i++) {
        if(p[i]+q[i]+b[i]<=f) ans=a[i];
    }
    cout<<(ans==0?-1:ans);
}

原文地址:https://www.cnblogs.com/mollnn/p/12324931.html