题目链接:
http://codeforces.com/problemset/problem/544/D
题目思路:
处理出每两座岛屿之间的最短能使用多长的桥,以及两座岛最长可以用多长的桥,然后按前者从小到大排序,为了使得间隔长的桥不影响间隔短的桥,我们给这个间隔长的桥分配一个最大的满足条件的,保证短的尽可能留给岛间隔小的用。
此外还要处理的就是multiset中桥的下标,代码中打得麻烦了,先对一定长度的桥编号,塞入对应编号的vector,在用index数组记录取到该vector中的哪个了。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll MAXN = 2e5+5;
struct node
{
ll r,l;
}C[MAXN];
struct Node
{
ll Min,Max,id,ans;
}d[MAXN];
multiset<ll>ss;
ll index[MAXN];
map<ll,ll>mm;
bool cmp(Node a,Node b)
{
return a.Min>b.Min;
}
bool cmp2(Node a,Node b)
{
return a.id<b.id;
}
vector<ll>v[MAXN];
int main()
{
ll tot=0;
ll n,m;
cin>>n>>m;
for(ll i=1;i<=n;i++){
cin>>C[i].l>>C[i].r;
d[i-1].id = i-1;
d[i-1].Min=C[i].l-C[i-1].r;
d[i-1].Max=C[i].r-C[i-1].l;
}
for(ll i=1;i<=m;i++){
ll a;cin>>a;
if(!mm[a])mm[a]=++tot;
ll x=mm[a];
v[x].push_back(i);
ss.insert(a);
}
sort(d+1,d+n,cmp);
for(ll i=1;i<n;i++){
multiset<ll>::iterator idx = ss.upper_bound(d[i].Max);
if(idx==ss.begin()){
cout<<"No"<<endl;
return 0;
}
idx--;
if((*idx)<d[i].Min){
cout<<"No"<<endl;
return 0;
}
ll xx=mm[(*idx)];
d[i].ans=v[xx][index[xx]];
index[xx]++;
ss.erase(idx);
}
sort(d+1,d+n,cmp2);
cout<<"Yes"<<endl;
for(ll i=1;i<n;i++){
cout<<d[i].ans<<" ";
}
cout<<endl;
}