Fundraising【Gym - 101889F】【树状数组+最大值处理层层推进】

题目链接


  哇哇哇!!!好题啊,昨晚比赛时一直卡在了第6组,当时爆零,极度尴尬……不过嘛,这都是ACMer的必经之路了,然后今早起来改了下,心态调整好,想了下,发现了处理问题的方式,然后就给过了。(其实昨晚上已经找到问题所在了,只是太急了,毕竟只有2个小时,剩下半小时的时候就自闭了……)

  我们要查询这样的最大值:要么“魅力值B”和“财富值F”绝对小于的条件下的最大能融资,以及B与F相等的情况下的最大融资的总和是多少?——题意就是指要么强制大于,要么强制等于的情况下的最大融资问题。

  当然是树状数组!但是,处理方式得独特些(我昨晚怎么没能想到呢……呜呜呜QWQ),看来我还是不理解树状数组!

  这道题当时一直卡在这样的一组数据上:

3

1 5 10

2 2 10

3 6 10

  答案是20。

  当时,就一直想得处理出怎么弄内部冲突的问题,就是外围虽然包住了,但是内部存在两个这样的区间,他们是相互冲突的,怎么办?QAQ……然后今天的时候想了想,那我们为什么不把关系层层向上递推呢?好主意!那么我们不如把树状数组换成取符合条件的包含最大值,然后按一个条件的绝对升序走,诶,但这又发现了个问题,原来的测试样例(一)、(三)怎么都过不了,怎么办?就是存在有一边相等,而另一边不相等的情况!那为什么不能降序排另一组条件呢!

  我的天!过了……好了,更加自闭了,哎……为自己的心态感到担忧,一定要调整自己的心态……呜呜呜


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INf 0x3f3f3f3f
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 2e5 + 5;
int N, cnt;
ll trie[maxN], lsan[maxN];
struct node
{
    ll B, F, D;
    node(ll a=0, ll b=0, ll c=0):B(a), F(b), D(c) {}
}a[maxN];
bool cmp(node e1, node e2) { return e1.B == e2.B?(e1.F > e2.F):(e1.B < e2.B); }
void update(ll i, ll val)
{
    if(i == 0) return;
    while(i < maxN)
    {
        trie[i] = max(val, trie[i]);
        i += lowbit(i);
    }
}
ll query(ll i)
{
    ll ans = 0;
    while (i)
    {
        ans = max(trie[i], ans);
        i -= lowbit(i);
    }
    return ans;
}
void pre_did()
{
    
}
void init()
{
    cnt = 0;
    memset(trie, 0, sizeof(trie));
    memset(a, 0, sizeof(a));
}
int main()
{
    while(scanf("%d", &N)!=EOF)
    {
        init();
        for(int i=1; i<=N; i++)
        {
            scanf("%lld%lld%lld", &a[i].B, &a[i].F, &a[i].D);
            lsan[++cnt] = a[i].F;
        }
        sort(a+1, a+1+N, cmp);
        sort(lsan+1, lsan+1+cnt);
        ll ans = 0, sum = 0;
        int ls_len = (int)(unique(lsan+1, lsan+1+cnt) - lsan - 1);
        for(int i=1; i<=N; i++)
        {

            if(i!=N && a[i].B == a[i+1].B && a[i].F == a[i+1].F)
            {
                a[i+1].D += a[i].D;
                continue;
            }
            sum = query(lower_bound(lsan+1, lsan+1+ls_len, a[i].F) - lsan - 1);
            update(lower_bound(lsan+1, lsan+1+ls_len, a[i].F) - lsan, sum + a[i].D);
        }
        ans = query(ls_len);
        printf("%lld\n", ans);
    }
    return 0;
}
/*
3
1 5 10
2 2 10
3 6 10
 ans = 20;
*/

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wuliwuliii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值