1. 程式人生 > >Codeforces 555 B. Case of Fugitive

Codeforces 555 B. Case of Fugitive

getc 最小 http bits 可以轉化 cmp 不可 char class

\(>Codeforces \space 555 B. Case of Fugitive<\)

題目大意 : 有 \(n\) 個島嶼有序排列在一條線上,第 \(i\) 個島嶼的左端點為 \(l_i\) 右端點為 \(r_i\) ,島嶼之間兩兩不相交, 現在對於每一個 \(1 \leq i < n\)\(i\) 島嶼要和第 \(i + 1\) 島嶼之間建一座橋,橋的長度左右端點必須得在島上。現在有 \(m\) 座已經長度建好的橋梁,試找出一種島嶼和橋匹配的方案,使得任意兩座島嶼之間的橋梁長度都滿足要求

\(2?≤?n, m?≤?2 \times 10^5\ 1?≤?l_i?≤?r_i?≤?10^{18}\)

解題思路 :

問題可以轉化為 \(n-1\) 條線段匹配 \(m\) 個點,使得點在線段之內,找出一種匹配完所有線段的方案

有一種顯然的貪心策略,排完序後對於每一個點盡可能選右端點小的線段

可以感性理解,因為點是遞增的,右端點越小的線段越往後越不可能有匹配

考慮將所有線段和點按照左端點排序, 從左到右枚舉每一個點為其找線段匹配

維護一個優先隊列來存線段,每枚舉到一個點就將所有左端點小於它的線段加進優先隊列

對於每一個點取優先隊列中 \(r_i\) 最小的進行匹配,如果發現某一時刻最小的 \(r_i \leq\) 當前的點

那麽對於之後的所有點,這個線段都無法被匹配了,必然是無解,否則就匹配完輸出方案


/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
    int f = 0, ch = 0; x = 0;
    for(; !isdigit(ch); ch = getchar()) if(ch == ‘-‘) f = 1;
    for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
    if(f) x = -x;
}
#define int ll
#define N (500005)
int l[N], r[N], Ans[N], n, m;
struct Node{ int x, id; } a[N];
struct Seg{
    int l, r, id;
    bool operator < (const Seg &A) const{ return r > A.r; }
}s[N];
inline bool cmp(Seg A, Seg B){ return A.l < B.l; }
inline bool cmp2(Node A, Node B){ return A.x < B.x; }
priority_queue<Seg> pq;
main(){
    read(n), read(m);
    if(m < n - 1) return puts("No"), 0;
    for(int i = 1; i <= n; i++) read(l[i]), read(r[i]);
    for(int i = 1; i <= m; i++) read(a[i].x), a[i].id = i;
    for(int i = 1; i < n; i++) 
        s[i] = (Seg){l[i+1] - r[i], r[i+1] - l[i], i};
    sort(s + 1, s + n, cmp);
    sort(a + 1, a + m + 1, cmp2);
    int p = 1;
    for(int i = 1; i <= m; i++){
        while(a[i].x >= s[p].l && p < n) pq.push(s[p]), p++;
        if(pq.empty()) continue; 
        if(pq.top().r < a[i].x) return puts("No"), 0;
        Seg now = pq.top(); pq.pop(); Ans[now.id] = a[i].id;
    }
    for(int i = 1; i < n; i++) if(!Ans[i]) return puts("No"), 0;
    puts("Yes");
    for(int i = 1; i < n; i++) printf("%lld ", Ans[i]);
    return 0;
}

Codeforces 555 B. Case of Fugitive