Hacker, pack your bags!

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

猜你喜欢

转载自www.cnblogs.com/CADCADCAD/p/12227475.html
今日推荐