Codeforces 555 B. Case of Fugitive

Posted mangoyang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 555 B. Case of Fugitive相关的知识,希望对你有一定的参考价值。

(>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 imes 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的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #724 (Div. 2) B. Prinzessin der Verurteilung(暴力枚举)

Codeforces B. Mouse Hunt(强连通分解缩点)

Codeforces 982 B. Bus of Characters(模拟一个栈)

Codeforces1161 B. Chladni Figure(枚举因子+check)

Educational Codeforces Round 90 (Rated for Div. 2) B. 01 Game

Codeforces1541 B. Pleasant Pairs(暴力,复杂度分析)