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;
}