Round Marriage - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
![](https://i-blog.csdnimg.cn/blog_migrate/0c56ce48cee0fd00c915262976e1a4c8.png)
二分最大的距离,对于左集合的任何一个点x,他能连边的点就是右集合中的区间[lx,rx]。x右移,对应的集合也会右移。所以左集合的任意子集,对应右集合的交集中元素个数都应该大于他。设左区间[a,b]右区间[la,Rb],那么
#include <bits/stdc++.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
#define x first
#define y second
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
typedef pair<int,int> PII;
typedef pair<char,int> PCI;
typedef long long LL;
//typedef __int128 i128;
typedef unsigned long long ULL;
const int N=4e5+10,INF = 0x3f3f3f3f ;
const double eps = 1e-7;
LL n,L;
LL a[N],b[N * 2];
void init()
{
cin>>n>>L;
for(int i=1;i<=n;i++ )
cin >> a[i];
sort(a+1,a+n+1);
// 读入男人的位置 并排序
for(int i=n + 1;i<=n * 2 ;i++)
cin >> b[i];
sort(b+1 + n ,b+n * 2+1);
// 读入女人的位置 并排序
for(int i=1;i<=n;i++)
b[i] = b[i + n ] - L ;
for(int i=n*2+1;i<=3 * n; i ++ )
b[i] = b[i-n] + L;
}
// 将男人的位置a 不断往右移动 找到最小的 与b的匹配值
// L >= 2 * n
int judge(int len)
{
int ml=-INF,mr = INF;
for(int i=1;i<=n;i ++ )
{
int l=lower_bound(b+1,b+1+3*n,a[i]-len) - b -i;
// l 在b 中 找到 大于等于 a[i]-len ,b[l] >= a[i] - len
int r=upper_bound(b+1,b+1+3*n,a[i] + len) - b- i;
// r 在b 中 找到 大于 a[i]-len b[r] > a[i] + len
--r; // b[r] <= a[i] + len
// b 在 [l,r] 中 使得 a 属于 [a[i]-len,a[i]+len]
ml = max(ml,l);
mr = min(mr,r);
}
return ml <= mr;
}
void solve()
{
init();
int l=0,r=L;
while(l < r )
{
int mid = l + r >> 1;
if(judge(mid)) r = mid;
else l = mid + 1;
}
cout << l << endl;
}
int main()
{
// freopen("1.txt","r",stdin);
// ios
int T=1;
// cin>>T;
while(T -- )
{
solve();
}
return 0;
}