「AGC032E」 Modulo Pairing

「AGC032E」 Modulo Pairing

传送门

如果所有数都 (<lfloor frac m 2 floor),一个自然的想法是对所有数排序过后大小搭配,这样显然是最优秀的。

(a<b<c<d),则 (max{a+c,b+d}>max{a+d,b+c})

那么现在数字不一定满足这个要求。

容易发现事实上就是我们使一些数全部减少了 (m),且满足这些数在配对时有 (a_i+a_jge 0)

显然我们把大的数减少 (m) 会更加优秀,且减少的越多越好。我们现在需要的就是找到这个分界点。

显然这个东西是可以二分的,然后就做完了。

/*---Author:HenryHuang---*/
/*---Never Settle---*/
/*---Never Enough---*/
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
int a[maxn];
int n,m;
int check(int mid){
	int mx=0;
	for(int i=1;i<=mid;++i){
		mx=max(mx,(a[i]+a[2*mid-i+1])%m);
	}
	int mn=2e9;
	int l=2*mid+1,r=2*n;
	while(l<=r) mn=min(mn,a[l]+a[r]),++l,--r;
	if(mn>=m) return 1;
	else return 0;
}
int c(int mid){
	int mx=0;
	for(int i=1;i<=mid;++i){
		mx=max(mx,(a[i]+a[2*mid-i+1])%m);
	}
	int l=2*mid+1,r=2*n;
	while(l<=r) mx=max(mx,(a[l]+a[r])%m),++l,--r;
	return mx;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=2*n;++i) cin>>a[i];
	sort(a+1,a+2*n+1);
	int l=0,r=n,ans=r;
	while(l<=r){
		int mid=(l+r)>>1;
		if(check(mid)){
			ans=min(ans,mid);
			r=mid-1;
		}
		else l=mid+1;
	}		
	cout<<c(ans)<<'
';
	return 0;
}
在繁华中沉淀自我,在乱世中静静伫立,一笔一划,雕刻时光。
原文地址:https://www.cnblogs.com/HenryHuang-Never-Settle/p/solution-AGC032E.html