Problem F – Fundraising

A prestigious politician aiming for presidency next year is planning a fundraising dinner for her campaign.
She has a list of some wealthy people in the country and wants to invite them in a way that the
amount of money raised is as great as possible.
Sometimes wealthy people have futile behavior and don’t like the idea that someone richer or prettier
than them exists. Every time someone like this meets another person who is strictly prettier, but not
strictly richer, then an argument ensues. Likewise, if they meet another person who is strictly richer,
but not strictly prettier, an argument occurs as well. These two situations are the only possible causes
of an argument involving two persons. Thus, two persons do not have an argument if one of them is
strictly prettier and strictly richer than the other. Also, two persons do not have an argument if they
are equally rich and equally pretty.
Since the presidential candidate wants to raise as much money as possible, an argument should be
avoided at all costs, as it could ruin the campaign. Given the characteristics of some wealthy people in
the country, you must find a guest list that maximizes the donations while ensuring that no argument
will happen during the dinner.
Input
The first line contains an integer N (1 ≤ N ≤ 105
) representing the number of possible guests with
known characteristics. Each of the next N lines describes a possible guest with three integers B, F and
D (1 ≤ B, F, D ≤ 109
), indicating respectively the person’s beauty, his/her fortune, and how much this
person will donate if invited.
Output
Output a single line with an integer indicating the maximum sum of donations if guests are invited
so that no argument will happen during the dinner.
Sample input 1
4
1 2 50
2 1 50
2 2 30
1 1 30
Sample output 1
60
Sample input 2
3
3 3 3
5 5 3
2 2 3
Sample output 2
9
Sample input 3
3
2 8 13
1 4 12
2 1 16
Sample output 3
25

题意:

有n个人,每个人都有两个值和一个贡献,现在要邀请一些人使得贡献最大,如果一个人的两个值不全部大于或小于或等于任意一个一个人的值,那么就是不允许的。

题解:

像多校时候那一道斜着走收集金币的题目,这道题就是把相等的都合在一起,然后找绝对大于,注意放到树状数组的时候是a[i].x>a[i-1].x,要不然会把2,1 2,2这种加到一起。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
#define ll long long
#define pa pair<int,ll>
#define mp(a,b) make_pair(a,b)
struct node
{
    int x,y;
    ll val;
    bool operator< (const node& a)const
    {
        if(x==a.x)
            return y<a.y;
        return x<a.x;
    }
}a[N];
int x[N],y[N];
    int n;

int lowbit(int x)
{
    return x&(-x);
}
ll sum[N];
void add(int x,ll val)
{
    for(int i=x;i<=n;i+=lowbit(i))
        sum[i]=max(sum[i],val);
}
ll query(int x)
{
    ll ans=0;
    for(int i=x;i>=1;i-=lowbit(i))
        ans=max(ans,sum[i]);
    return ans;
}
vector<pa>vec;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d%lld",&a[i].x,&a[i].y,&a[i].val),x[i]=a[i].x,y[i]=a[i].y;

    sort(x+1,x+1+n),sort(y+1,y+1+n);
    int allx=unique(x+1,x+1+n)-x-1,ally=unique(y+1,y+1+n)-y-1;
    for(int i=1;i<=n;i++)
        a[i].x=lower_bound(x+1,x+1+allx,a[i].x)-x,a[i].y=lower_bound(y+1,y+1+ally,a[i].y)-y;

    sort(a+1,a+1+n);
    ll ans=0;
    for(int i=1;i<=n;i++)
    {

        if(a[i].x!=a[i-1].x){
            for(int j=0;j<vec.size();j++)
                add(vec[j].first,vec[j].second);
            vec.clear();
        }
        if(i!=n){
            if(a[i].x==a[i+1].x&&a[i].y==a[i+1].y){
                a[i+1].val+=a[i].val;
                continue;
            }
        }
        ll val=query(a[i].y-1)+a[i].val;
        vec.push_back({a[i].y, val});
        ans=max(ans,val);
    }
    printf("%lld\n",ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值