P7514 省选联考 2021 A/B 卷 卡牌游戏 - 洛谷 (luogu.com.cn)
极差 = 最大值 - 最小值,这意味着你在值域上 找一个区间。
区间越大越容易合法,区间越小越优。

cpp
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e6 + 10;
LL a[N], b[N];
struct node {
LL x;
int ki; // 0:a,1:b
int id;
} t[N];
bool cmp(node na, node nb) {
if (na.x != nb.x) {
return na.x < nb.x;
}
else {
return na.ki < nb.ki;
}
}
int v[N], ha[N], hb[N];
int main () {
ios::sync_with_stdio(false);
cin.tie(0);
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i ++) {
cin >> a[i];
t[i] = {a[i], 0, i};
}
for (int i = 1; i <= n; i ++) {
cin >> b[i];
t[i + n] = {b[i], 1, i};
}
sort (t + 1, t + n * 2 + 1, cmp);
memset(v, 0, sizeof(v));
memset(ha, 0, sizeof(ha));
memset(hb, 0, sizeof(hb));
LL ans = 2e9;
int sumv = 0, sumb = 0;
// sumv 检查区间内是不是 n 个数都有
// sumb 检查区间内最多有 m 个单个 b
int r = 0;
for (int l = 1; l <= 2 * n; l ++) {
while (r < 2 * n && (sumv < n || sumb > m)) {
// r 不能越界是硬性条件,而 sumv < n 和 sumb > m 是不合法区间的判断
// 也就是如果这两个条件有一个不符,整个区间就不合法
r ++;
if (v[t[r].id] == 0) {
sumv ++;
}
v[t[r].id] ++;
if (t[r].ki == 0) {
ha[t[r].id] = 1;
if (hb[t[r].id] == 1) {
sumb --;
}
}
else {
hb[t[r].id] = 1;
if (ha[t[r].id] == 0) {
sumb ++;
}
}
}
if (sumb <= m && sumv == n) {
// 保证是合法并非越界终止循环
ans = min(t[r].x - t[l].x, ans);
}
v[t[l].id] --;
if (v[t[l].id] == 0) {
sumv --;
}
if (t[l].ki == 0) {
ha[t[l].id] = 0;
if (hb[t[l].id] == 1) {
sumb ++;
}
}
else {
hb[t[l].id] = 0;
if (ha[t[l].id] == 0) {
sumb --;
}
}
}
cout << ans << "\n";
return 0;
}