题目大意
两个长度为 n (2<=n<=10^5)的数组a,b,给定 a [ 1 ] 的取值为1<=a [ 1 ]<=m (1<=m<=10^9),给定a [ 2 ]~a [ n ]以及数组 b 的值,在操作前可对a,b进行排序,每次操作分别删掉a,b中的任意一个元素,致使最终得到一个长度为k的两个数组,使得1<=i<=k,都有a[i]<b[i]。问对于所有a [ 1 ]的取值,得到合法数组的最小总操作数是多少。
思路
先不管a [ 1 ]是多少。除去a [ 1 ],剩下的a和b能匹配的还是能匹配。所以先将n-1个a与n个b配对,用b去配a,两个数组从小到大排列,若当前的a [ i ]< b [ j ]则配对成功 i++,j++;若当前a [ i ] >= b [ j ],则 i 不动,j++,增大b再去比较。这个过程中记录未被匹配的b的最大值maxn是多少,若m的值大于或等于这个最大值则操作数+1,否则操作数即为n减去n-1个a与n个b的成功匹配数。
code
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 10;
int a[N], b[N];
int n, m;
void solve() {
cin >> n >> m;
for (int i = 1; i < n; ++i) cin >> a[i];
for (int i = 1; i <= n; ++i) cin >> b[i];
sort(a + 1, a + n);
sort(b + 1, b + n + 1);
int j = 1;
bool f = 0;
int ans = 0, maxn = -1;
for (int i = 1; i < n; ++i)//用a去匹配b
{
//当不合法时,b往后移,让b增大再比较
while (j < n && a[i] >= b[j]) {
maxn = max(maxn, b[j]);
j++;
}
if (j == n) {
f = 1;
//a的第i位可以配对
if (a[i] < b[j]) {
if (m < maxn) ans = m * (n - i - 1);
else {
ans = (n - i - 1) * (maxn - 1);
ans += (n - i) * max((int)0, m - maxn + 1);
}
}
//a的第i位不能配对
else ans = m * (n - (i - 1) - 1) + max((int)0, m - b[n] + 1);
break;
}
j++;
}
if (!f) ans = max((int)0, m - b[n] + 1);
cout << ans << '\n';
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) solve();
return 0;
}