「AGC032E」 Modulo Pairing

「AGC032E」 Modulo Pairing

传送门

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

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

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

容易发现事实上就是我们使一些数全部减少了 \(m\),且满足这些数在配对时有 \(a_i+a_j\ge 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)<<'\n';
	return 0;
}
posted @ 2021-04-19 15:03  Henry__Huang  阅读(45)  评论(0编辑  收藏  举报