题解 P9314 [EGOI2021] Railway / 瑞士铁路

题意

P9314 [EGOI2021] Railway / 瑞士铁路

分析

$nm \le 4 \times 10^6$,考虑分别任意两辆相向行驶的车相遇的位置。

对于任意两辆车的相遇位置枚举隧道是不现实的,观察到隧道互不重叠且坐标单调递增,于是可以二分找到最后一个左端点小于等于相遇位置的区间。

注意判断相遇位置是否在整数点上,避免浮点误差可以分类讨论。

时间复杂度 $O(nm \log t)$。

代码

//the code is from chenjh
#include<cstdio>
#include<algorithm>
#define MAXT 100005
using namespace std;
int s,t,m,n;
int a[MAXT],b[MAXT];
int c[2002],d[2002];
int main(){
    scanf("%d%d%d%d",&s,&t,&m,&n);
    for(int i=1;i<=t;i++) scanf("%d",&a[i]);
    for(int i=1;i<=t;i++) scanf("%d",&b[i]);
    for(int i=1;i<=m;i++) scanf("%d",&c[i]);
    for(int i=1;i<=n;i++) scanf("%d",&d[i]);
    for(int i=1;i<=m;i++)for(int j=1;j<=n;j++){
        int tm=max(c[i],d[j]);//后开始的时间。
        int rs=s+c[i]-tm+d[j]-tm;//同时出发时剩下的路程。
        if(rs<=0) continue;//某一方已经到达。
        int x=tm-c[i]+(rs>>1);//从苏黎世出发相遇的位置。
        int y=upper_bound(a+1,a+t+1,x)-a-1;//二分查找最后一个左端点小于等于相遇位置的隧道区间。 
        if(rs&1){//不在整数点上相遇。
            if(a[y]<=x && x<b[y]) return puts("YES"),0;//相遇点实际为 x+0.5,所以相等也可能在该隧道区间内。
        }
        else{
            if(a[y]<x && x<b[y]) return puts("YES"),0;//在整数点上,不可取等。
        }
    }
    puts("NO");
    return 0;
}
posted @ 2024-02-02 16:17  Chen_Jinhui  阅读(12)  评论(0)    收藏  举报  来源