题目传送门
感谢
的讲解!!
这是一道很棒的题~~ 模型转化也比较需要思考
首先这个题可能会无从下手,仔细观察可以发现一个性质,那就是一段新郎一定对应一段连续的新娘,可以用简单证明下,如果存在一个匹配,有一个新郎跨越了另一个新郎的话,那么这肯定不会最优,因为我们可以交换这两个新郎所对应的新娘,使其多出来的一段距离消去,一定会让答案更优。有了这个性质之后我们考虑二分答案,把新娘的序列扩展成三倍,分别代表从左往右跨越起点,从右往左跨越起点和不跨越起点三种情况,把两个序列排序,首先找到第一个新郎能到达的新娘的区间
,由于新郎必须连续对应一段新娘,那么下一个新郎能到达的新娘的区间就是
与自己原本能到达区间的交集, 这样如果存在一个新郎没有选择的区间那么当前答案就是不可行的,否则就是可行的,这样就做完了,复杂度
Codes
#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)
#define mid ((l + r) >> 1)
using namespace std;
const int maxn = 6e5 + 10, mod = 20000909;
int n, L, a[maxn], b[maxn];
bool check(int x) {
int l = 1, r = n * 3;
For(i, 1, n) {
while(a[i] - b[l] > x)
++ l;
while(b[r] - a[i] > x)
-- r;
++ l, ++ r;
}
return l <= r;
}
void File() {
freopen("queue.in", "r", stdin);
freopen("queue.out", "w", stdout);
}
void Init() {
scanf("%d%d", &n, &L);
For(i, 1, n) scanf("%d", &a[i]);
For(i, 1, n) {
scanf("%d", &b[i]);
b[i + n] = b[i] + L;
b[i + 2 * n] = b[i] - L;
}
sort(a + 1, a + n + 1);
sort(b + 1, b + n * 3 + 1);
}
void Solve() {
int l = 0, r = L + 1 >> 1, ans;
while(l <= r) {
if(check(mid))
ans = mid, r = mid - 1;
else
l = mid + 1;
}
printf("%d\n", qpow(2, ans));
}
int main() {
File();
Init();
Solve();
return 0;
}