Codeforces 1445D. Divide and Sum(找规律+组合数)

   日期:2020-11-04     浏览:153    评论:0    
核心提示:Codeforces 1445D. Divide and Sum题目大意给一个2n2n2n的序列,将他们分成ppp和qqq两个长为nnn的序列,求所有情况下,将ppp升序和将qqq降序后的∑i=1n∣pi−qi∣\sum_{i=1}^n|p_i-q_i|∑i=1n​∣pi​−qi​∣之和。n≤150000n\leq150000n≤150000题解考虑每两个数的贡献,将整个序列排序后,对半分成两份,左半边在ppp中的数量和右半边在qqq中的数量一定会相同,左半边在qqq中的数量和左半边在ppp

Codeforces 1445D. Divide and Sum

题目大意

  • 给一个 2 n 2n 2n的序列,将他们分成 p p p q q q两个长为 n n n的序列,求所有情况下,将 p p p升序和将 q q q降序后的 ∑ i = 1 n ∣ p i − q i ∣ \sum_{i=1}^n|p_i-q_i| i=1npiqi之和。
  • n ≤ 150000 n\leq150000 n150000

题解

  • 考虑每两个数的贡献,将整个序列排序后,对半分成两份,左半边在 p p p中的数量和右半边在 q q q中的数量一定会相同,左半边在 q q q中的数量和左半边在 p p p中的数量也一定相同, 那么只可能是左边的 p p p和右边的 q q q匹配,右边的 q q q和左边的 p p p匹配,
  • 也就是说,整个序列无论怎么分,任意一种情况的贡献都是大的一半减去小的一半,然后再乘上方案数 ( 2 ∗ n n ) \tbinom{2* n}{n} (n2n)即可。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 300010
#define ll long long
#define md 998244353
ll a[N], f[N];
ll ksm(ll x, ll y) { 
	if(!y) return 1;
	ll l = ksm(x, y / 2);
	if(y % 2) return l * l % md * x % md;
	return l * l % md;
}
int main() { 
	int n, i, j;
	scanf("%d", &n);
	for(i = 1; i <= 2 * n; i++) scanf("%lld", &a[i]);
	sort(a + 1, a + 2 * n + 1);
	ll ans = 0;
	for(i = 1; i <= n; i++) { 
		ans = (ans + a[i + n] - a[i]) % md;
	}
	f[0] = 1;
	for(i = 1; i <= 2 * n; i++) f[i] = f[i - 1] * i % md;
	printf("%lld\n", ans * f[n * 2] % md * ksm(f[n], md - 2) % md * ksm(f[n], md - 2) % md);
	return 0;
}
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服