zoukankan      html  css  js  c++  java
  • AGC032E Modulo Pairing

    AGC032E

    有个(2*n)的数组(a_i),你要给其中的数两两配对,使得两个数之和模(M)的最大值最小。

    (nle 10^5)

    (mle 10^9)


    简化题意:对于两个数(x)(y),若(x+y<M),则答案和(x+y)(max);若(x+ygeq M),则答案和(x+y-m)(max)

    先考虑一个简化的问题:如果要两两配对,使得它们的和的最大值最小,怎么做?

    一眼就可以看出做法:小的和大的依次配对。两眼可以想出证明:考虑如果存在四个数(ale ble cle d),假如存在(max(a+d,b+c)>max(a+c,b+d))。如果(max(a+d,b+c)=a+d),由于(a+d le b+d)矛盾;如果(max(a+d,b+c)=b+c),由于(b+cle b+d)矛盾。所以((a,d)(b,c))配对总是比((a,c)(b,d))优。

    其实也可以发现,如果是要让最小值最大,还是小的和大的依次配对最优。

    所以如果要求和在一个区间内,最小配最大的方式,可以尽可能地将所有和压在这个区间内。

    然后是一个结论:取(x+y<M)(x+yge M)的数,分别在数组的左右两边。

    这里搞一个性质:设有(ale b le cle d),且(a+c<Mand b+dge M),那么将((a,c)(b,d))替换成((a,b)(c,d))会更优。

    证明:即证(max(a+c,b+d-M)ge max(a+b,c+d-M))。显然(a+ble a+c),并且因(d< Mle M+a),所以(c+d-Mle a+c)

    于是如果有“相交”的情况,就可以调整成包含。

    那么一直调整下去,最后它们就分别在数组的两边了。

    枚举这个分界点,然后两边以最小配最大原则来搞。这样是(O(n^2))的,但是注意到,如果合法,两边的最大值是随着这个分界点递增而递增的;分界点太大则左半边不合法,分界点太小则右半边不合法。于是可以二分解决。


    using namespace std;
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 200010
    int n,m;
    int a[N];
    int ans;
    int calcf(int l,int r){
    	int f=0;
    	for (int i=1;l+i-1<r-i+1;++i){
    		if (a[l+i-1]+a[r-i+1]>=m)
    			return -1;
    		f=max(f,a[l+i-1]+a[r-i+1]);
    	}
    	return f;
    }
    int calcg(int l,int r){
    	int g=0;
    	for (int i=1;l+i-1<r-i+1;++i){
    		if (a[l+i-1]+a[r-i+1]<m)
    			return -1;
    		g=max(g,a[l+i-1]+a[r-i+1]);
    	}
    	return g;
    }
    void work(){
    	ans=m-1;
    	int l=0,r=n/2;
    	while (l<=r){
    		int mid=l+r>>1;
    		int f=calcf(1,mid*2),g=calcg(mid*2+1,n);
    		if (f==-1)
    			r=mid-1;
    		else if (g==-1)
    			l=mid+1;
    		else{
    			ans=min(ans,max(f,g-m));
    			r=mid-1;
    		}
    	}
    }
    int main(){
    	freopen("in.txt","r",stdin);
    	scanf("%d%d",&n,&m);
    	n*=2;
    	for (int i=1;i<=n;++i)
    		scanf("%d",&a[i]);
    	sort(a+1,a+n+1);
    	work();
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    SpringBoot入门篇--读取资源文件配置
    SpringBoot入门篇--使用Thymeleaf模板引擎进行页面的渲染
    SpringBoot入门篇--热部署
    NOI2017 游记
    BZOJ 2754 【SCOI2012】 喵星球上的点名
    codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
    BZOJ 4407 于神之怒加强版
    BZOJ 2956 模积和
    BZOJ 4584 【APIO2016】 赛艇
    BZOJ 4591 【SHOI2015】 超能粒子炮·改
  • 原文地址:https://www.cnblogs.com/jz-597/p/13741865.html
Copyright © 2011-2022 走看看