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=1n∣xi−yi∣ 。求所有分法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;
}