Chieh's Blog

Because Of Coding

R310 DIV2 D. Case of Fugitive

Chieh posted @ 2015年6月28日 12:01 in codeforces , 202 阅读

飞机票:http://codeforces.com/contest/556/problem/D

题意:给你n个区间li,ri,且ri<li+1,(1<=i<n),li<=ri,然后给你m座桥,每个有个长度ai,然后要求把桥搭在区间上,且满足桥的长度

大于等于li+1-ri,且小于等于ri+1-li,求能否用桥把所有的相邻区间连接起来,并且输出每个相邻区间对应的桥下标。

分析:起先一看以为是二分图,但是看边太多直接放弃。这里我们 可以知道一个东西。就是相邻区间需要的桥的最大值和最小值,假设两个相邻区间li,ri  li+1,ri+1,我们定义他们的坐标为i,则可知需要的最小长度为li+1-ri,最大长度为ri+1-li,假设为最小为le最大为ri,接着我们再把m条桥排序,从小到大。接着运用贪心看看怎么贪?假设当前要判断桥i属于哪个区间le ri,我们必须把所有可以用桥i的区间找出来,然后找右端点最小的,为什么?因为大伙都可以用它,当然我们要使用剩余使用量最小的来接受它,不然给别人,它都亏。搞到这里就知道怎么贪了吧。就是把le ri按左区间排序,如果一样不用管。然后来个优先队列,假如当前的le<=桥i的长度,就把它加到优先队列,为什么??因为我们不知道它满不满足,但是只要它的右端点最小,然后比桥i的长度还短,那么直接就No了,因为别人都比它好。优先队列干嘛用的?就是取右端点最小的,因为我们前面判断过的比较小的le可能要在这个时候用到。总体复杂的就是O(n*logn)了。然后啪啪啪就可以AC了

/*
Author:Chieh
Because Of Coding
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <stack>
#include <vector>
#include <queue>
#define LL long long
#define INF 1e9
#define EPS 1e-9
using namespace std;
const int maxn=2*123456;
LL l[maxn],r[maxn];
struct he
{
    int id;
    LL l,r;
    bool operator<(const he& a)const
    {
        return r>a.r;
    }
} Sky[maxn];
LL ai[maxn];
struct he1
{
    LL val;
    int id;
} Sky1[maxn];
int can[maxn];
int n,m;
bool cmp(he1 a,he1 b)
{
    return a.val<b.val;
}
void init()
{
    for(int i=1; i<=n; i++)
    {
        scanf("%I64d%I64d",&l[i],&r[i]);
    }
    for(int i=1; i<=m; i++)
    {
        scanf("%I64d",&Sky1[i].val);
        Sky1[i].id=i;
    }
    sort(Sky1+1,Sky1+1+m,cmp);
}
bool cmp2(he a,he b)
{
    if(a.l!=b.l)return a.l<b.l;
    return a.r<b.r;
}
priority_queue<he> pq;
void play()
{
    int st=0;
    for(int i=2; i<=n; i++)
    {

        LL a1=l[i]-r[i-1];
        LL a2=r[i]-l[i-1];
        st++;
        Sky[st].l=a1;
        Sky[st].r=a2;
        Sky[st].id=st;
    }
    sort(Sky+1,Sky+1+st,cmp2);
    while(!pq.empty())pq.pop();
    int now=1;
    for(int i=1; i<=m; i++)
    {
        int id=Sky1[i].id;
        LL val=Sky1[i].val;
        while(now<=st)
        {
            if(Sky[now].l<=val)
            {
                pq.push(Sky[now]);
                now++;
            }
            else
            {
                break;
            }
        }
        if(pq.empty())continue;
        he aa=pq.top();
        pq.pop();
        if(aa.r<Sky1[i].val)
        {
            printf("No\n");
            return;
        }
        int idx=aa.id;
        can[idx]=id;
    }
    if(!pq.empty()||now!=st+1)
    {
        printf("No\n");
        return ;
    }
    printf("Yes\n");
    for(int i=1; i<=st; i++)
    {
        printf("%d ",can[i]);
    }
    printf("\n");

}
int main()
{

    while(scanf("%d%d",&n,&m)!=EOF)
    {
        init();
        play();
    }
//   cout << "Hello world!" << endl;
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter