Codeforces1445D. Divide and Sum
Divide and Sum
题目大意
给定一个长度为\(2n\)的数组,将数组分成两个长度为n的数组p,q,将p从小到大排序,将q从大到小排序,对于每种分法,\(ans=\displaystyle\sum_{i=1}^{n}|p_i-q_i|\),现在求总的答案
Solution
考虑将a先从小到大排序后,可以分成前后两块
其中因为p,q的长度是固定的,所以我们可以知道
在p中的左块个数与q中的右块个数相同,在p中的右块个数与在q中的左块个数相同
因为是排序的,所以对于每种方案,一定是右块的数去减左块的数
所以可以把左块的数看成负数,右块的数为正数,将整个数组累加,设和为\(tot\)
而所有的排列总数是\(C_{2n}^{n}\),
所以总的答案\(\displaystyle ans=tot \cdot C_{2n}^{n}\)
Code
#include <cstdio>
#include <algorithm>
#define MO 998244353
#define M 300001
#define open(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;
int n,m,i,a[M];
long long t,ans,f[M];
long long ksm(long long x,int y)
{
long long sum=1;
while (y)
{
if (y&1) sum=sum*x%MO;
x=x*x%MO;
y>>=1;
}
return sum;
}
int main()
{
open("1445D");
scanf("%d",&n);
m=n<<1;
for (i=1;i<=m;i++)
scanf("%d",&a[i]);
sort(a+1,a+m+1);
for (i=1;i<=n;i++)
{
ans=(ans+a[i+n]-a[i])%MO;
}
f[1]=1;
for (i=2;i<=m;i++)
f[i]=f[i-1]*i%MO;
t=ksm(f[n],MO-2);
ans=ans*f[m]%MO*t%MO*t%MO;
printf("%lld",ans);
return 0;
}
如果自己说什麽都做不到而什麽都不去做的话,那就更是什麽都做不到,什麽都不会改变,什麽都不会结束.