显然桥a能连在li+1−ri<=a<=ri+1−li
于是问题就转化为n−1个活动,每个活动可以在[li,ri]时间内进行,给出m个空闲时间,问能否完成
非常经典的活动分配问题
按ri升序排序,ri相同按li升序排列,multiset维护时间点,随便搞一下即可
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MEM(a,x) memset(a,x,sizeof(a))
#define pii pair<int,int>
#define pll pair<ll,ll>
const int N = 2e5+5;
pll a[N];
multiset<ll>b;
void init(int n){
#define l first
#define r second
for(int i=0;i<n-1;++i){
ll minVal=a[i+1].l-a[i].r;
ll maxVal=a[i+1].r-a[i].l;
a[i]={minVal,maxVal};
}
}
bool cmp(const pll&a,const pll&b){
if(a.second!=b.second){
return a.second<b.second;
}
return a.first<b.first;
}
bool slove(int n){
init(n);
sort(a,a+n-1,cmp);
for(int i=0;i<n-1;++i){
auto it=b.lower_bound(a[i].first);
if(it==b.end()||*it>a[i].second){
return 0;
}
b.erase(it);
}
return 1;
}
int main()
{
//freopen("/home/yang/Desktop/r.txt","r",stdin);
int n,m;
while(~scanf("%d%d",&n,&m)){
for(int i=0;i<n;++i){
scanf("%lld%lld",&a[i].first,&a[i].second);
}
b.clear();
for(int i=0;i<m;++i){
ll x;
scanf("%lld",&x);
b.insert(x);
}
puts(slove(n)?"YES":"NO");
}
return 0;
}