Hacker, pack your bags!
谨记sort()
函数是\(O(nlog(n))\)的复杂度。
我们对每一个旅途进行遍历,分别找到开始符合条件的那一个旅途,这里的复杂度可以用二分来降低,但是我们还需要找到一个满足条件而且权值最大的旅途,如果我们此时进行遍历的话,就是\(O(n^2)\)的复杂度了,那么怎么降低其复杂度呢, 这个时候就需要对其进行预处理,在每一个位置找到它满足条件所需要的最少花费。这里需要注意一个性质,在旅途的长度相等的情况下,起始日期更晚的旅途也是符合条件的,那么我们就可以用一个单调栈对其进行维护,然后再在后面遍历的时候\(O(1)\)查询即可。
代码:
// Created by CAD on 2020/1/20.
#include <iostream>
#include <vector>
#include <algorithm>
#define inf 0x3f3f3f3f
#define INF 0x7fffffffffffffff
#define ll long long
using namespace std;
const int maxn=2e5+5;
struct node{
int l,r;
ll w;
bool operator <(node &b)
{
return l<b.l;
}
}nod[maxn];
vector<node> v[maxn];
vector<ll> w[maxn];
inline bool judge(node &a,node &b)
{
return a.l>b.r;
}
int main()
{
int n,x; cin>>n>>x;
ll ans=INF;
for(int i=1;i<=n;++i)
{
int l,r;
ll c;
scanf("%d%d%lld",&l,&r,&c);
nod[i]={l,r,c};
v[r-l+1].push_back({l,r,c});
}
for(int i=1;i<=x;i++)
sort(v[i].begin(),v[i].end());
for(int i=1;i<=x;++i)
{
if(v[i].empty()) continue;
w[i].push_back(v[i].back().w);
for(int j=v[i].size()-2;j>=0;--j)
w[i].push_back(min(w[i].back(),v[i][j].w));
}
for(int i=1;i<=n;++i)
{
int k=x-(nod[i].r-nod[i].l+1);
if(k<1) continue;
if(v[k].empty()) continue;
else{
int l=0,r=int(v[k].size())-1;
int pos=inf;
while(l<=r)
{
int mid=(l+r)>>1;
if(judge(v[k][mid],nod[i])) pos=min(pos,mid),r=mid-1;
else l=mid+1;
}
if(pos==inf) continue;
ll minn=w[k][w[k].size()-pos-1];
ans=min(ans,nod[i].w+minn);
}
}
if(ans==INF) cout<<-1<<endl;
else cout<<ans<<endl;
return 0;
}
CAD加油!欢迎跟我一起讨论学习算法,QQ:1401650042