Divide and Sum

题目:
http://codeforces.com/contest/1445/problem/D

给定一个数组 a a a,有 2 n 2n 2n个数,分成两个数组 p , q p,q p,q p p p是非递减, q q q是非递增。 f ( p , q ) = ∑ i = 1 n ∣ p i − q i ∣ f(p,q)=\sum_{i=1}^{n}|p_i-q_i| f(p,q)=i=1npiqi,计算所有 f ( p , q ) f(p,q) f(p,q)的和。

思路:
先对数组 a a a排序,然后仔细分析一下可以得出 p , q p,q p,q数组对应位置的数字的下标一个在数组 a a a中的 1 ∼ n 1\sim n 1n,一个在 n + 1 ∼ 2 n n+1\sim 2n n+12n。所以任意一种情况 f ( p , q ) = ∑ i = n + 1 2 n a i − ∑ i = 1 n a i f(p,q)=\sum_{i=n+1}^{2n}a_i-\sum_{i=1}^{n}a_i f(p,q)=i=n+12naii=1nai。然后有 ( 2 n n ) {2n\choose n} (n2n)种情况。

#include<bits/stdc++.h>
#define mod 998244353
#define ll long long
using namespace std;
const int N=300009;
int n;
ll p[N],p1[N],a[N],ans=0;
ll qpow(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1)
            res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
ll cal(int a,int b){
    if(b>a||b<0)
        return 0;
    return p[a]*p1[b]%mod*p1[a-b]%mod;
}
int main(){
    p[0]=1;
    for(int i=1;i<N;i++)
        p[i]=p[i-1]*i%mod;
    p1[N-1]=qpow(p[N-1],mod-2);
    for(int i=N-2;i>=0;i--)
        p1[i]=p1[i+1]*(i+1)%mod;
    scanf("%d",&n);
    for(int i=1;i<=2*n;i++)
        scanf("%lld",&a[i]);
    sort(a+1,a+2*n+1);
    for(int i=n+1;i<=2*n;i++)
        ans=(ans+a[i])%mod;
    for(int i=1;i<=n;i++)
        ans=(ans-a[i]%mod+mod)%mod;
    cout<<cal(2*n,n)%mod*ans%mod;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值