tokitsukaze and Soldier

算法 : 二叉堆

思路 : 类似于超市,首先我们可以想到对于每个限制si, 那么我们只要取所有限制大于等于si的前si大即可 那么如何做,主席树区间维护,固定顺序,从si大的向小的枚举,那么每次删除的时候就可以用小根堆维护出来

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>

#define int long long
using namespace std;
const int N = 1e5 + 10;
struct node{
    int v, s;
    bool operator<(const node& other) const{
        return s > other.s;
    }
}th[N];
int n, ans;
signed main()
{
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> n;
    priority_queue<int, vector<int>, greater<int>> heap;
    for(int i = 0; i < n; i ++)
    {
        int a, b;
        cin >> a >> b;
        th[i] = {a, b};
    }
    int res = 0;
    sort(th, th + n);
    for(int i = 0; i < n; i ++)
    {
        auto t = th[i];
        heap.push(t.v);
        res += t.v;
        while((long long)heap.size() > t.s)
        {
            int v = heap.top();
            res -= v;
            heap.pop();
        }
        ans = max(ans, res);
    }
    cout << ans << endl;
    return 0;
}