acwing 145

#include <bits/stdc++.h>

#define IOS ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)

#define _zero(a) memset(a, 0, sizeof(a))

#define endl '\n'

//#define int long long

#define mp make_pair

#define x first

#define y second

#define all(a) (a).begin(), (a).end()

#define rall(a) (a).rbegin(), (a).rend()

#define PII pair<int, int>

typedef long long ll;

typedef double dd;

typedef long double ld;

using namespace std;

//const int inf = 1e10;

//const int M = 998244353;

const ld pi = atan2(0, -1);//arctan(y/x);

const ld eps = 1e-4;

const int maxn = 1e4 + 100;

int m;

int f[maxn];

int p[maxn], d[maxn];

//二叉堆

int heap[maxn], n = 0;

void up(int p)//向上调整

{

    while(p > 1){

        if(heap[p] < heap[p / 2]){//子节点>父节点,不满足大根堆性质

            swap(heap[p], heap[p / 2]);

            p /= 2;

        }

        else break;

    }

}

void insert(int val)//往大根堆中插入

{

    heap[++n] = val;

    up(n);

}

int GetTop()//返回二叉堆堆顶权值

{

    return heap[1];

}

void down(int p){

    int s = p * 2;//p的左子节点

    while(s <= n){

        if(s < n && heap[s] > heap[s + 1]) s++;//左右子节点中取较大值

        if(heap[s] < heap[p]){//子节点大于父节点,不满足大根堆性质

            swap(heap[s], heap[p]);

            p = s, s = p * 2;

        }

        else break;

    }

}

void Extract(){//把堆顶从二叉堆中移除

    heap[1] = heap[n--];

    down(1);

}

void Remove(int k){//将储存在下标为k处的节点从二叉堆中删除

    heap[k] = heap[n--];

    up(k), down(k);

}

bool cmp(int a, int b){

    return d[a] < d[b];

}

void solve()

{

    n = 0;

    for(int i = 1; i <= m + 5; i++) f[i] = i;

    sort(f + 1, f + 1 + m, cmp);

    for(int i = 1; i <= m; i++){

        int t = f[i];

        if(d[t] > n) insert(p[t]);

        else if(d[t] == n && p[t] > GetTop()) {

            Extract();

            insert(p[t]);

        }

    }

    int ans = 0;

    while(n){

        ans += GetTop();

        Extract();

    }

    cout << ans << endl;

}

signed main()

{

    IOS;

    while(cin >> m){

        for(int i = 1; i <= m; i++) cin >> p[i] >> d[i];

        solve();

    }

    return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值