【L,R的特点】codeforce 822C Hacker, pack your bags!

来源:互联网 发布:开淘宝店进货渠道 编辑:程序博客网 时间:2024/06/11 05:10
codeforce 822C     Hacker, pack your bags!

给出x,几个区间(l,r)以及其值,选择两个不相交的区间,要求其和为x,并cost最小。

难点: n(区间个数)<= 2*10^5,要求两个区间不相交。
解决方法:  均是根据L,R特点:

1.根据其中一个排序,如果对L排序,那么在i区间前面的区间的L一定是满足小于当前L,那么前面的区间如果R满足小于当前L,那么他对

当前区间以下的区间全部不相交。

#include<bits/stdc++.h>using namespace std;typedef long long LL;//#pragma comment(linker, "/STACK:102400000,102400000")const double PI = acos(-1.0);const double eps = 1e-6;//const int INF=0x3f3f3f3f;const LL INF = 1e18;const LL mod = 1e9+7;const int N=2*100005;const int M = 2500000;struct node{    int l,r;    int day;    int cost;    bool operator <(const node &a) const{        return r>a.r;    }}a[N];bool cmp(node a,node b){    return a.l < b.l;}map<int,int> mp;int main(){    int n,x;    scanf("%d%d",&n,&x);    for(int i = 0; i < n; i++){        scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].cost);        a[i].day = a[i].r-a[i].l+1;    }    sort(a,a+n,cmp);    priority_queue<node> Q;    mp.clear();    LL mi = INF;    for(int i = 0; i < n; i++){        while(!Q.empty()){            node tmp = Q.top();            if(tmp.r < a[i].l){                Q.pop();                int f = tmp.day;                if(mp.find(f) == mp.end())                    mp[f] = tmp.cost;                else                    mp[f] = min(mp[f],tmp.cost);            }            else                break;        }        Q.push(a[i]);        if(mp.find(x-a[i].day) == mp.end())            continue;        else            mi = min(mi,(LL)mp[x-a[i].day]+(LL)a[i].cost);    }    if(mi == INF)        puts("-1");    else        printf("%I64d\n",mi);    return 0;}



2. 将区间的L,R直接记录下来,从0到最远距离循环过来,同样根据当前位置如果是R,那么以后的L全于其不相交。
#include<bits/stdc++.h>using namespace std;typedef long long LL;//#pragma comment(linker, "/STACK:102400000,102400000")const double PI = acos(-1.0);const double eps = 1e-6;//const int INF=0x3f3f3f3f;const LL INF = 1e18;const LL mod = 1e9+7;const int N = 2*1e5+10;const int M = 2500000;vector<pair<int,int> > l[N],r[N];LL mp[N];int main(){    int n,x;    scanf("%d%d",&n,&x);    for(int i = 0; i < n; i++){        int a,b,c;        scanf("%d%d%d",&a,&b,&c);        l[a].push_back(make_pair((b-a+1),c));        r[b].push_back(make_pair((b-a+1),c));    }    LL mi = INF;    for(int i = 0; i < N; i++)        mp[i] = INF;    for(int i = 1; i < N; i++){        for(int j = 0; j < l[i].size(); j++){            if(x-l[i][j].first <= 0)                continue;            if(mp[x-l[i][j].first] != INF)                mi = min(mi,mp[x-l[i][j].first]+(LL)l[i][j].second);        }        for(int j = 0; j < r[i].size(); j++){            mp[r[i][j].first] = min(mp[r[i][j].first],(LL)r[i][j].second);        }    }    if(mi == INF){        puts("-1");    }    else        printf("%I64d\n",mi);    return 0;}



3.根据二分的思想,明显先要按照r-l+1排序,但处理出来是还是一个范围,那么还得将R作为第二关键词排序。因为这样对于一个L,比一个区间的R小,那么这个区间和前面的区间都不相交,那么如果预处理 相同(r-l+1)中前缀最小值,那么就能强行二分计算一波了。
#include<bits/stdc++.h>using namespace std;typedef long long LL;//#pragma comment(linker, "/STACK:102400000,102400000")const double PI = acos(-1.0);const double eps = 1e-6;//const int INF=0x3f3f3f3f;const LL INF = 1e18;const LL mod = 1e9+7;const int N=2*100005;const int M = 2500000;struct node{    int l,r;    int day;    int cost;    int micost;}a[N];bool cmp(node a,node b){    if(a.day != b.day)        return a.day < b.day;    return a.r < b.r;}LL Binseach(int l,int r,int eday,int el){    LL ans = INF;    int mid;    while(l <= r){        mid = l+(r-l>>1);        if(a[mid].day < eday)            l = mid+1;        else if(a[mid].day == eday){            if(a[mid].r < el){                l = mid+1;                ans = min(ans,(LL)a[mid].micost);            }            else                r = mid-1;        }        else            r = mid-1;    }    return ans;}int main(){    int n,x;    scanf("%d%d",&n,&x);    for(int i = 0; i < n; i++){        scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].cost);        a[i].day = a[i].r-a[i].l+1;        a[i].micost = a[i].cost;    }    sort(a,a+n,cmp);    for(int i = 1; i < n; i++){        if(a[i].day == a[i-1].day)            a[i].micost = min(a[i].micost,a[i-1].micost);    }    LL mi = INF;    for(int i = 0; i < n; i++){        LL ans = Binseach(0,n-1,x-a[i].day,a[i].l);        //printf("%d %d\n",i,ans);        mi = min(mi,(LL)ans+(LL)a[i].cost);    }    if(mi == INF)        puts("-1");    else        printf("%I64d\n",mi);    return 0;}


原创粉丝点击