CodeForces - 556D 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 adjacentislands. 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?≤?rili?+?1?≤?y?≤?ri?+?1and 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.

Input

The first line contains integers n (2?≤?n?≤?2·105) and m (1?≤?m?≤?2·105) — the number of islands and bridges.

Next n lines each contain two integers li and ri (1?≤?li?≤?ri?≤?1018) — the coordinates of the island endpoints.

The last line contains m integer numbers a1,?a2,?...,?am (1?≤?ai?≤?1018) — the lengths of the bridges that Andrewid got.

Output

If it is impossible to place a bridge between each pair of adjacent islands in the required manner, print on a single line "No" (without the quotes), otherwise print in the first line "Yes" (without the quotes), and in the second line print n?-?1numbers b1,?b2,?...,?bn?-?1, which mean that between islands i and i?+?1 there must be used a bridge number bi.

If there are multiple correct answers, print any of them. Note that in this problem it is necessary to print "Yes" and "No" in correct case.

Examples

Input

4 41 47 89 1012 144 5 3 8

Output

Yes2 3 1 

Input

2 211 1417 182 9

Output

No

Input

2 11 11000000000000000000 1000000000000000000999999999999999999

Output

Yes1 

Note

In the first sample test you can, for example, place the second bridge between points 3 and 8, place the third bridge between points 7 and 10 and place the first bridge between points 10 and 14.

In the second sample test the first bridge is too short and the second bridge is too long, so the solution doesn‘t exist.

题目大意:

给你n-1个区间和m个点。问你能否从m个点中找出n-1个点,分别包含于n-1个区间中。如果能,输出Yes,并输出任何一种匹配结果;否则输出No。

贪心。

先将区间按其左端点排序,再将点按其坐标排序。

依次考察每个点,直至考察完所有点(1..m):

1、将所有左端点不大于该点的区间送入优先队列。区间右端点越小,优先级越高。

2、若队列非空,则pop。若区间右端点比该点小,则跳出循环(实际上已经可以输出No了,因为后面没有更小的点与该区间对应);若区间右端点不小于该点,则建立区间到这点的对应关系(贪心,因为右端点较大的区间更有可能匹配到较大的点)。

最后考察是否所有的区间都建立了到点的对应关系,是则输出Yes及对应关系;否则输出No。

排序(谈几点自己的理解,C++学完对运算符重载啥的了解后,再回来想一想)。

//结构体&数

//优先队列用结构体:struct cmp & greater/less<int>

//排序用函数:int cmp() & int cmp()

//如果只涉及一种偏序关系,不必太在意,也可以在结构体内部写,如果涉及偏序关系较多,最好拿出来写清楚

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>

typedef long long lol;

using namespace std;

const int maxn=200000;

struct tnode
{
    lol mmin;
    lol mmax;
    int seq;
};
tnode node[maxn+5];//1..n-1的区间

struct tlen
{
    lol lenth;
    int seq;
};
tlen len[maxn+5];//1..m的桥长

int cmp1(tnode a,tnode b)
{
    return a.mmin<b.mmin;
}

int cmp2(tlen a,tlen b)
{
    return a.lenth<b.lenth;
}

struct cmp3
{
    bool operator()(const int a,const int b)
    {
        return node[a].mmax>node[b].mmax;
    }
};

int bridge[maxn+5];//i区间对应的桥

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);

    lol l0,r0,l,r;
    for(int i=1;i<=n;i++)
    {
        scanf("%lld%lld",&l,&r);
        if(i>=2)
        {
            node[i-1].mmin=l-r0;
            node[i-1].mmax=r-l0;
            node[i-1].seq=i-1;
        }
        l0=l;
        r0=r;
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%lld",len+i);
        len[i].seq=i;
    }

    sort(node+1,node+n,cmp1);
    sort(len+1,len+m+1,cmp2);

    priority_queue<int,vector<int>,cmp3> q;
    memset(bridge,0,sizeof(bridge));
    for(int i=1,j=1;i<=m;i++)
    {
        for(;j<=n-1&&node[j].mmin<=len[i].lenth;j++)
                q.push(j);
        bool flag=true;
        if(!q.empty())
        {

            int tmp=q.top();q.pop();
            if(node[tmp].mmax<len[i].lenth)
                flag=false;
            else
                bridge[node[tmp].seq]=len[i].seq;
        }
        if(!flag)
            break;
    }

    bool flag=true;
    for(int i=1;i<=n-1;i++)
        if(bridge[i]==0)
        {
            flag=false;
            break;
        }
    if(flag)
    {
        printf("Yes\n");
        for(int i=1;i<=n-1;i++)
        {
            if(i<n-1)
                printf("%d ",bridge[i]);
            else
                printf("%d\n",bridge[i]);
        }
    }
    else
        printf("No\n");

    return 0;
}

原文地址:https://www.cnblogs.com/acboyty/p/9792159.html

时间: 2024-10-25 18:17:58

CodeForces - 556D Case of Fugitive (贪心+排序)的相关文章

Codeforces 556D - Case of Fugitive

556D - Case of Fugitive 思路:将桥长度放进二叉搜索树中(multiset),相邻两岛距离按上限排序,然后二分查找桥长度匹配并删除. 代码: #include<bits/stdc++.h> using namespace std; #define ll long long const int N=2e5+5; struct node { ll x; ll y; int id; bool operator <(const node &a)const { ret

codeforces 555B Case of Fugitive

题目连接: http://codeforces.com/problemset/problem/555/B 题目大意: 有n个岛屿(岛屿在一列上,可以看做是线性的,用来描述岛屿位置的是起点与终点),m个桥,给出每个岛屿的位置和桥的长度,问是否可以把n个岛屿连起来? 解题思路: 排序+贪心,对于n个岛屿,相邻的两个之间起点和端点可以转化为n-1个连接桥的长度区间,把区间升序排列. 对于m个桥升序排列,对于每一个桥枚举每个可以合法覆盖的区间,选取最优的,选取的时候满足L<bridge_length<

Codeforces 555B - Case of Fugitive 搭桥

题意:给出n段路和m座桥.每段路的两个端点一维坐标表示.要从m座桥中选出一些桥搭在每两条相邻的路上,使得这些路全部连通.每两条相邻的路之间只能搭一座桥,且桥的两端必须恰好分别落在两段路上.如果存在一种搭桥方法,则输出Yes并按题目给定的路形成的空隙的顺序输出每座桥的序号,若不能则输出No. 题意换个说法实际上就是给定n - 1个区间和m个数,问是否能从m个数中选出n - 1个数,恰好分别落在n - 1个区间内. 觉得可以用贪心做,开始想了下因为区间有两个端点,而且位置任意,有点不好处理.后来就想

codeforces 555b//Case of Fugitive// Codeforces Round #310(Div. 1)

题意:有n-1个缝隙,在上面搭桥,每个缝隙有个ll,rr值,ll<=长度<=rr的才能搭上去.求一种搭桥组合. 经典问题,应列入acm必背300题中.属于那种不可能自己想得出来的题.将二元组[ll,rr]排序(ll相同时再rr),长度x排序(升序).一个全局优先队列pq(rr小的顶部).for循环,对每个x,将ll比它小的放入优先队列pq,如果pq仍为空,说明这块桥用不上,不为空,看top的rr是否大于x,如果大于,这块桥就能用上,并且给当前的top一定是可行的. 乱码: #pragma co

【贪心+排序】国王游戏

[贪心+排序]国王游戏 Time Limit: 1000MS Memory Limit: 131072KB Description 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排成一排,国王站在队伍的最前面.排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果. 国王不希

Codeforces 442B Andrey and Problem(贪心)

题目链接:Codeforces 442B Andrey and Problem 题目大意:Andrey有一个问题,想要朋友们为自己出一道题,现在他有n个朋友,每个朋友想出题目的概率为pi,但是他可以同时向多个人寻求帮助,不过他只能要一道题,也就是如果他向两个人寻求帮助,如果两个人都成功出题,也是不可以的. 解题思路:贪心,从概率最大的人开始考虑,如果询问他使得概率变大,则要询问. #include <cstdio> #include <cstring> #include <a

uva 10026 Shoemaker&#39;s Problem(贪心+排序)

虽然是个水题,但是在一些细节上wa了几次,好像不支持'\b'退格符号,我用在了输出空格那,结果wa了...白白 wa了几次...题意是看的题解..今天只写了两道题,速度有点慢,得加快了,以后得先认真读懂题目,题目读懂了 就相当于做出来一半然后仔细动脑想想,有想法了再敲,不能盲目的做题.另外,热烈祝贺今天c++ primer看到 了100页 思路: 这道题是让给的数据是每件工作需要做的天数和每耽误一天所需要的费用,让求一个序列使得付费最小,如果有相同答 案把字典树最小的输出...输出的是序号,该件

Round 310(Div.1) B. Case of Fugitive

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

Codeforces 439D Devu and his Brother(排序)

题目链接:Codeforces 439D  Devu and his Brother 题目大意:Devu和他的哥哥互相深爱着对方,我确信他们是搞基的,为此我还去查了一下Devu是男人名还是女人名,但是后来发现His Brother,所以可以证明,他们就是搞基的.题目很简单,父亲给了他们两个人分别一个数组.但是Devu希望自己最小的数都可以不必哥哥最大的数小,现在对数组中的数有两种操作,一种是加1,一种是减1,问最少进行几次操作可以使得两个数组满足要求. 解题思路:将两个数组合并在一起,然后排序,