天天看點

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