有n个小岛,每一个小岛是直线型的,他们不相互相交,第i个小岛所占的区间是[li, ri],而且, ri < li+1 对于所有的 1 ≤ i ≤ n-1。现在要将相邻的小岛用桥连接起来。现在有一条桥的长度是a,第i个岛和第i+1个岛能够连接的条件是,存在x,y使得 li ≤ x ≤ ri, li+1 ≤ y ≤ ri+1 且 y - x = a成立。
现在有m条桥,每条桥最多被使用一次,问能否把这些岛连接起来。
样例解释:在这个样例中,把第2条桥两个端点放在3和8,把第三条桥两个端点放在7和10,把第一条桥的端点放在10和14。
Input
单组测试数据。 第一行有两个整数n (2 ≤ n ≤ 2*10^5) 和 m (1 ≤ m ≤ 2*10^5),表示岛的数目和桥的数目。 接下来n行,每行有两个整数 li 和 ri (1 ≤ li ≤ ri ≤ 10^18),表示岛的两个端点。 接下来一行有m个整数 a1, a2, ..., am (1 ≤ ai ≤ 10^18),表示每一条桥的长度。
Output
如果能够将n座岛连接起来输出YES,否则输出NO。
Input示例
4 4 1 4 7 8 9 10 12 14 4 5 3 8
Output示例
YES#include <cstring> #include <iostream> #include <set> #include <algorithm> using namespace std; typedef long long int ll; const int MAXN = 2e5 + 5; ll l[MAXN]; ll r[MAXN]; int n, m; struct Seg { ll minLen; ll maxLen; }; Seg segs[MAXN]; multiset<ll> bridges; bool cmp(const Seg &a, const Seg &b) { if (a.maxLen == b.maxLen) { return a.minLen < b.minLen; } return a.maxLen < b.maxLen; } bool solve() { for (int i = 0; i < n - 1; i++) { multiset<ll>::iterator it = bridges.lower_bound(segs[i].minLen); if (it == bridges.end() || (*it) > segs[i].maxLen) { return false; } bridges.erase(it); } } int main() { cin >> n >> m; for (int i = 0; i < n; i++) { cin >> l[i] >> r[i]; } for (int i = 0; i < n - 1; i++) { segs[i].maxLen = r[i + 1] - l[i]; segs[i].minLen = l[i + 1] - r[i]; } sort(segs, segs + n - 1, cmp); ll len; for (int i = 0; i < m; i++) { cin >> len; bridges.insert(len); } bool result = solve(); if (result) { cout << "YES" << endl; } else { cout << "NO" << endl; } return 0; }