题目链接
哇哇哇!!!好题啊,昨晚比赛时一直卡在了第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;
*/