Round 310(Div.1) B. Case of Fugitive
Andrewid the Android is a galaxy-famous detective. He is now chasing a criminal hiding on the planet Oxa-5, the planet almost fully covered with water.
The only dry land there is an archipelago of n narrow islands located in a row. For more comfort let‘s represent them as non-intersecting segments on a straight line: island i has coordinates [li,?ri], besides, ri?<?li+1 for 1?≤?i?≤?n?-?1.
To reach the goal, Andrewid needs to place a bridge between each pair of adjacent islands. A bridge of length a can be placed between the i-th and the (i?+?1)-th islads, if there are such coordinates of x and y, that li?≤?x?≤?ri, li?+?1?≤?y?≤?ri?+?1 and y?-?x?=?a.
The detective was supplied with m bridges, each bridge can be used at most once. Help him determine whether the bridges he got are enough to connect each pair of adjacent islands.
- #include <stdio.h>
- #include <string.h>
-
- #include <queue>
- #include <vector>
- #include <algorithm>
-
- const int N = 200000 + 5;
-
- long long left[N];
- long long right[N];
-
- struct segment_t
- {
- long long left;
- long long right;
- int index;
- } segment[N];
-
- struct left_order
- {
- bool operator() (const segment_t& first, const segment_t& second)
- { return first.left < second.left; }
- };
-
- struct right_order
- {
- bool operator() (const segment_t& first, const segment_t& second)
- {
- if (first.right != second.right)
- return first.right > second.right;
- return first.index < second.index;
- }
- };
-
- struct bridge_t
- {
- long long length;
- int index;
- } bridge[N];
-
- struct length_order
- {
- bool operator() (const bridge_t& first, const bridge_t& second)
- { return first.length < second.length; }
- };
-
- int answer[N];
-
- int main()
- {
- #ifndef ONLINE_JUDGE
- freopen("input.txt", "r", stdin);
-
- #endif
- int n, m;
- scanf("%d %d", &n, &m);
- for (int i = 1; i <= n; ++i) {
- scanf("%I64d %I64d", &left[i], &right[i]);
- }
- for (int i = 1; i <= m; ++i) {
- scanf("%I64d", &bridge[i].length);
- bridge[i].index = i;
- }
- for (int i = 1; i < n; ++i) {
- segment[i].left = left[i+1] - right[i];
- segment[i].right = right[i+1] - left[i];
- segment[i].index = i;
- }
- std::sort(segment+1, segment+n, left_order());
- std::sort(bridge+1, bridge+1+m, length_order());
- std::priority_queue<segment_t, std::vector<segment_t>, right_order> pq;
- int ptr = 0;
- int assigned_count = 0;
- for (int i = 1; i <= m; ++i) {
- for (; ptr < n && segment[ptr].left <= bridge[i].length; ptr++) {
- pq.push(segment[ptr]);
- }
- for (; !pq.empty() && pq.top().right < bridge[i].length; pq.pop());
- if (pq.empty()) {
- continue;
- }
- assigned_count += 1;
- answer[pq.top().index] = bridge[i].index;
- pq.pop();
- }
- if (assigned_count == n - 1) {
- puts("Yes");
- for (int i = 1; i < n; ++i) {
- printf("%d ", answer[i]);
- }
- printf("\n");
- }
- else puts("No");
- return 0;
- }