题目链接:https://cn.vjudge.net/problem/CodeForces-555B

题目大意:n个岛屿,在一条线上,岛屿有起点和终点,有m座桥,问能不能用n-1座桥把岛屿连起来

思路:可以先把n个岛屿的位置  预处理成n-1个所需桥的长度范围,然后按照左端点升序排列,把桥的长度按照升序排列

对于每个桥筛选出满足条件的岛屿区间  因为对于区间已经升序了,所以选择一个较小的右端点,可以保证其他的区间有更多的选择

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+5;
struct node {
    ll maxx,minn,id;
    node(){}
    node(ll aa,ll bb,ll cc):maxx(aa),minn(bb),id(cc){}
    bool operator<(const node &M)const{
        return minn<M.minn;
    }
}pos[maxn];
struct node1 {
    ll val,id;
    node1(){}
    node1(ll aa,ll bb):val(aa),id(bb){}
    bool operator<(const node1 &M)const{
        return val<M.val;
    }
};
struct node2 {
    ll val,id;
    node2(){}
    node2(ll aa,ll bb):val(aa),id(bb){}
    bool operator<(const node2 &M)const{
        return val>M.val;
    }
};
vector<node1> v;
ll l[maxn],r[maxn],n,m,ans[maxn];
bool solve() {
    priority_queue <node2> q;
    for(int i=0,j=0;i<m;i++) {
        while(!q.empty() && q.top().val<v[i].val) q.pop();
        for(;;j++) {
            if(pos[j].minn<=v[i].val&&v[i].val<=pos[j].maxx) q.push(node2(pos[j].maxx,pos[j].id));
            else break;
        }
        if(q.empty())continue;
        ans[q.top().id] = v[i].id;
        q.pop();
    }
    for(int i=0;i<n-1;i++) if(!ans[i])return false;
    return true;
}
int main()
{
    scanf("%lld%lld",&n,&m);
    for(int i=0;i<n;i++) {
        scanf("%lld%lld",&l[i],&r[i]);
    }
    for(int i=1;i<n;i++) {
        pos[i-1].maxx = r[i] - l[i-1];
        pos[i-1].minn = l[i] - r[i-1];
        pos[i-1].id = i-1;
    }
    sort(pos,pos+n-1);
    for(int i=0;i<m;i++) {
        ll val;
        scanf("%lld",&val);
        v.push_back(node1(val,(ll)(i+1)));
    }
    if(m<n-1) {
        printf("No\n");
        return 0;
    }
    sort(v.begin(),v.end());
    if(solve()) {
        printf("Yes\n");
        for(int i=0;i<n-2;i++) {
            printf("%lld ",ans[i]);
        }
        printf("%lld\n",ans[n-2]);
    }
    else {
        printf("No\n");
    }
    return 0;
}