CodeForces 981F Round Marriage(二分+Hall)

F. Round Marriage
time limit per test:3 seconds
memory limit per test:256 megabytes
input:standard input
output:standard output

It's marriage season in Ringland!

Ringland has a form of a circle's boundary of length L. There are n bridegrooms and n brides, and bridegrooms decided to marry brides.

Of course, each bridegroom should choose exactly one bride, and each bride should be chosen by exactly one bridegroom.

All objects in Ringland are located on the boundary of the circle, including the capital, bridegrooms' castles and brides' palaces. The castle of the i-th bridegroom is located at the distance ai from the capital in clockwise direction, and the palace of the i-th bride is located at the distance bi from the capital in clockwise direction.

Let's define the inconvenience of a marriage the maximum distance that some bride should walk along the circle from her palace to her bridegroom's castle in the shortest direction (in clockwise or counter-clockwise direction).

Help the bridegrooms of Ringland to choose brides in such a way that the inconvenience of the marriage is the smallest possible.

Input

The first line contains two integers n and L (1n2105, 1L109) — the number of bridegrooms and brides and the length of Ringland.

The next line contains n integers a1,a2,,an (0ai<L) — the distances from the capital to the castles of bridegrooms in clockwise direction.

The next line contains n integers b1,b2,,bn (0bi<L) — the distances from the capital to the palaces of brides in clockwise direction.

Output

In the only line print the smallest possible inconvenience of the wedding, where the inconvenience is the largest distance traveled by a bride.

Examples
Input
Copy
2 4
0 1
2 3
Output
Copy
1
Input
Copy
10 100
3 14 15 92 65 35 89 79 32 38
2 71 82 81 82 84 5 90 45 23
Output
Copy
27

题目描述:

有n个新郎和新娘,要求把他们放在在一个长为L的环上,数组a表示能放新郎的位置,数组b表示能放新娘的位置。要求新郎新娘一一配对,配对的夫妇之间的距离为x,要使x最大值最小,问最小为多少。

思路:

使最大值最小想到二分距离,判断二分的函数就是判断当前距离x能不能使新郎新娘完美匹配。如果求最大匹配看是否等于n会tle,判断有没有完美匹配有Hall定理。

假设左集合任意子集为[a,b],对应与右集合为[La,Rb],根据Hall定理有,b-a<=Rb-La,移项得La-a<=Rb-b。

发现左右两边都只与当前边界有关,设当前点是b,因为a在b左边,所以La-a可以用前缀最大值mx维护,每次只要判断Rb-b和mx大小关系。

因为是在环上,按环的处理方法把a延长1倍,把b延长3倍。再进行二分。

#include<bits/stdc++.h>
#define sd(x) scanf("%d",&x)
#define lsd(x) scanf("%lld",&x)
#define ms(x,y) memset(x,y,sizeof x)
#define fu(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define all(a) a.begin(),a.end()
#define range(a,x,y) a+x,a+y+x
using namespace std;
using namespace __gnu_cxx;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> P;
const int N=2e5+99;
const ll mod=2147493647;
const int INF=1e9+7;
ll a[N<<1],b[N<<2],L;
int n;
bool check(int x)
{
    int mx=-INF;
    for(int i=1;i<=2*n;i++)
    {
        int rightt=(upper_bound(b+1,b+4*n+1,a[i]+x)-b-1)-i;
        int leftt=(upper_bound(b+1,b+4*n+1,a[i]-x-1)-b-1)-i;//因为是左包含,所以-1
        mx=max(mx,leftt);
        if(rightt<=mx) return 0;
    }
    return 1;
}
int main() 
{
    cin>>n>>L;
    fu(i,1,n) cin>>a[i];
    fu(i,1,n) cin>>b[i];
    sort(a+1,a+n+1);
    sort(b+1,b+n+1);
    fu(i,1,n) a[i]+=L,a[i+n]=a[i]+L;
    fu(i,1,3*n) b[i+n]=b[i]+L;
    ll l=0,r=L;
    while(l<r)
    {
        ll mid=(l+r)>>1;
        if(!check(mid)) l=mid+1;
        else r=mid;
    }
    cout<<l<<endl;
    return 0;
}

 

posted on 2020-12-15 17:12  Aminers  阅读(123)  评论(0编辑  收藏  举报

导航