题解:AT_agc032_e [AGC032E] Modulo Pairing

TH911

2024-11-20 15:45:01

Solution

题目传送门

个人Blog同步链接

题意分析

证明参见”相关证明“部分。

给定 n,m2n 个正整数 a_1,a_2,a_3,\cdots,a_{2n},将其分为 n 对,两两组成一队。若 x,y 为一对,则其权值为 (x+y)\bmod m

如果没有 \bmod m 这一个条件,那么其实很简单,将 a_1\sim a_{2n} 排序后”最大值与最小值相加求最大和“即可。

但是这里需要取模

考虑到 0\leq a_i<m,那么就有 0\leq x+y<2m。因此,每一对 (x,y) 的权值 (x+y)\bmod m 仅仅有两种可能:x+yx+y-m

那思路就很明显了,我们要想使权值和的最大值最小,那么就让每一对 (x,y) 的权值尽可能平均。

但这如何实现呢?

a_1\sim a_{2n} 排序后,我们一定可以找到一个位置 p,使得 [1,p] 存在配对方案使得所有配对 (a_i,a_j) 满足 a_i+a_j<m[p+1,2n] 存在配对方案使得所有配对 (a_i,a_j) 满足 a_i+a_j\geq m

然后将这两段分别进行“最大值与最小值相加”即可求得最大最小权值,答案即 :

\large \max\left(\max\limits_{i=1}^{\left\lfloor\frac p2\right\rfloor}(a_i+a_{p-i+1}),\max\limits_{i=p+1}^{\left\lfloor\frac {2n+p}2\right\rfloor}(a_i+a_{2n-i+1}-m)\right)

相关证明

约定

对于配对 $(a_i,a_j)$,若 $a_i+a_j<m$,记 $(a_i,a_j)$ 为 $x$ 型配对;若 $a_i+a_j\geq m$,记 $(a_i,a_j)$ 为 $y$ 型配对。 记 $a[l,r]$ 为序列 $a_l,a_{l+1},a_{l+2},\cdots,a_{r-1},a_r$。 **$a[1,p],a[p+1,2n]$ 均有可能不存在,以下暂不考虑此情况,参见引理 $5$**。 ### 引理 $1

引理 1y 型配对越多越好,即 p 越小越好。

考虑到对于所有 y 型配对 (a_i,a_j),其权值均为 a_i+a_j-m

又因为要求最大值最小,所以使 a_i+a_j 尽可能平均,使得能够组成的 y 型配对都组成 y 型配对,以此实现尽可能平均的目的。

引理 2

引理 2:一定存在整数 p\in[1,2n] 使得序列 a 分为两段 a[1,p],a[p+1,2n],其中 a[1,p] 只存在 x 型配对,a[p+1,2n] 只存在 y 型配对。

证明:

我们不妨从 (a_i,a_j) 的角度来思考。

a_i+a_j<m,我们记 (a_i,a_j)x 型配对;若 a_i+a_j\geq m,我们记 (a_i,a_j)y 型配对。

那么便转化为:找到 p,使 [1,p] 均为 x 型配对,[p+1,2n] 均为 y 型配对。

考虑到一个事实:若 (a_i,a_j) 为一对,则 a_i+a_j 的值不会因为 a_i,a_j 的位置改变而改变。

因此更改顺序不影响答案。

那么我们就可以将所有 x 型配对放至 [1,p],将所有 y 型配对放至 [p+1,2n]

即:存在整数 p\in[1,2n] 使得序列 a 分为 a[1,p],a[p+1,2n] 且满足 a[1,p] 可被划分为 \dfrac p2x 型配对,a[p+1,2n] 可被划分为 \dfrac {2n-p}{2}y 型配对。

引理 3

引理 3:最终答案为 \large \max\left(\max\limits_{i=1}^{\left\lfloor\frac p2\right\rfloor}(a_i+a_{p-i+1}),\max\limits_{i=p+1}^{\left\lfloor\frac {2n+p}2\right\rfloor}(a_i+a_{2n-i+1}-m)\right)

证明:

因为要求最大值尽可能的小,因此使和的值尽可能平均。即对于两段都采取”最大值与最小值配对“的方案。

故,正确性得证。

引理 4

引理 4:存在整数 p,使得 a[1,p] 均为 x 型配对,a[p+1,2n] 均为 y 型配对且无需改变 a 的元素顺序

证明:

由引理 2,一定能够将 a 划分为 a[1,p],a[p+1,2n]

考虑到 a 单调不降。

因此我们可以 n\sim1 尝试 p 值,结合引理 1,最后一个成立的 p 即为最终 p,且满足本引理。

引理 5

引理 5:当 a[1,p]a[p+1,2n] 不存在时,答案仍然正确。

  1. 即不存在 $x$ 型配对,答案显然正确。
  2. 即不存在 $y$ 型配对,答案显然正确。

引理 6

引理 6p 可以二分求得。

需要注意的是,我们是在 p 可以更小的时候尝试让 p 更小。

由于我们对 a 进行了排序,因此 a 具有单调性。

结合引理 1,本引理得证。

最终结论

(具体请参见代码注释)

结合引理 1\sim6,可得出以下最终结论。

a 排序以后二分 p 值直到 p 不满足 a[1,p],a[p+1,2n] 的定义即可。

最终答案即(p' 代表最后一个合法 p 值):

\large \max\left(\max\limits_{i=1}^{\left\lfloor\frac {p'}2\right\rfloor}(a_i+a_{p'-i+1}),\max\limits_{i=p'+1}^{\left\lfloor\frac {2n+p'}2\right\rfloor}(a_i+a_{2n-i+1}-m)\right)

AC 代码

//#include<bits/stdc++.h>
#include<algorithm> 
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<string>
#include<vector>
#include<cmath>
#include<ctime>
#include<deque>
#include<queue>
#include<stack>
#include<list>
using namespace std;
const int N=1e5;
int n,m,ans=2147483647,a[(N<<1)+1];
//check:是否可以使p更小
bool check(int x){//就用x代替p吧......
    x=(x<<1);
    int pl=0;
    for(int i=1;i<=x;i++){
        if(a[i]+a[x-i+1]>=m)return true;//a[1,p]依然存在x型配对
        pl=max(pl,a[i]+a[x-i+1]);
    }
    for(int i=x+1;i<=(n<<1);i++){
        if(a[i]+a[(n<<1)-i+x+1]<m)return false;//已经不满足y型配对的定义
        pl=max(pl,a[i]+a[(n<<1)-i+x+1]-m);
    }ans=min(ans,pl);
    return true;
}
int main(){
    /*freopen("test.in","r",stdin);
    freopen("test.out","w",stdout);*/

    scanf("%d %d",&n,&m);
    for(int i=1;i<=(n<<1);i++)scanf("%d",a+i);
    sort(a+1,a+(n<<1)+1);
    int l=0,r=n;//注意是二分[0,n],需要考虑不存在的情况
    while(l<=r){
        int mid=l+r>>1;
        if(check(mid))r=mid-1;
        else l=mid+1;
    }printf("%d\n",ans);

    /*fclose(stdin);
    fclose(stdout);*/
    return 0;
}