题解:P9314 [EGOI2021] Railway / 瑞士铁路
交了 发才过,喜提新纪录。
Solution P9314
Idea
显然是可以离线做的。我们预处理出两列车相遇的地点,判断是否在隧道里即可。
然后就是已知两列车出发时间 与 ,求两列车相遇地点的公式:
- :。
- :。
在本文章视角下,出发时间为 的火车从左边出发。
下面是证明:
如果一列火车在 时间从 点出发,相当于它从 时间从 点出发。
还不理解的话可以看图理解。

至于 ,可以看作把 的情况以 为对称轴对称了一下。
最后直接双指针检验即可。
#include<bits/stdc++.h>
#define ld long double
#define int long long
using namespace std;
const int N=1000005,M=6000005;
int l[N],r[N],n,cnt,s,t,m,a[N],b[N];
ld dis[M];
main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>s>>t>>m>>n;
for(int i=1;i<=t;i++){
cin>>l[i];
}
for(int i=1;i<=t;i++){
cin>>r[i];
}
for(int i=1;i<=m;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
cin>>b[i];
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(abs(a[i]-b[j])>=s)continue;
if(a[i]<=b[j])dis[++cnt]=(ld)(b[j]-a[i])+(ld)(s-(b[j]-a[i]))/2.0;
else dis[++cnt]=s-(ld)(a[i]-b[j])-(ld)(s-(a[i]-b[j]))/2.0;
}
}
sort(dis+1,dis+cnt+1);
int j=1;
for(int i=1;i<=cnt;i++){
while(dis[i]>=(ld)r[j]&&j<t) j++;
if(dis[i]>(ld)l[j]&&dis[i]<(ld)r[j]){
cout<<"YES";
return 0;
}
}
cout<<"NO";
return 0;
}

浙公网安备 33010602011771号