Codeforces Round 905 (Div. 3) G2. Dances (Hard Version) 双指针、排序

题目链接

题目大意

        两个长度为 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;
}

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值