Codeforces 1445D. Divide and Sum(思维,组合数)

Divide and Sum

题目传送门:

Divide and Sum

题目大意:

有一个长度为2n的数组a,现在将a分成两个数组p和q。将p数组按非递减排序成数组x,将q数组按非递增排序成数组y。对于每种分法ans= ∑ i = 1 n ∣ x i − y i ∣ \sum_{i=1}^{n}| x_i-y_i| i=1nxiyi 。求所有分法ans的和。

思路:

我们将a从小到大排序后,分成了左右相等长度的两块。其中p和q的长度也是固定的,且都为n。所以在p中左块的数量就等于在q中右块的数量,p中右块的数量就等于q中左块的数量。因为经过了排序,所以右块的数一定大于等于左块的数。
也就是说,整个序列无论怎么分,任意一种情况的贡献数都是大的一半减去小的一半,然后再乘上方案数C( 2*n , n )。

AC Code

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=3e5+10;
const LL mod=998244353;
LL a[N];
LL quick_pow(LL a,LL b)
{
    
    
    LL res=1;
    while(b)
    {
    
    
        if(b%2) res=res*a%mod;
        a=a*a%mod;
        b=b/2;
    }
    return res;
}
LL fac[N];
int main()
{
    
    
    int n;
    scanf("%d",&n);
    for(int i=1;i<=2*n;i++)
        scanf("%lld",&a[i]);
    LL ans=0;
    sort(a+1,a+1+2*n);
    for(int i=1;i<=n;i++)
        ans=(ans+a[i+n]-a[i])%mod;
    fac[0]=1;
    for(int i=1;i<=N;i++)
        fac[i]=fac[i-1]*i%mod;
    LL res=ans*fac[2*n]%mod*quick_pow(fac[n],mod-2)%mod*quick_pow(fac[n],mod-2)%mod;
    printf("%lld\n",res);
    //system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Stevenwuxu/article/details/109481404
今日推荐