【CF1445D】Divide and Sum 题解
题意简介
将一个长度为 2n 的数列平均分为两个子数列 p 和 q 后,p 按从小到大排序,q 按从大到小排序。
排序后,记 p 为 \(\{x_i\}\) ,q 为 \(\{y_i\}\) ,对每种划分方式,有 \(f(p,q) = \sum |x_i - y_i|\)
现在我们想要知道对所有的划分方案 \((p,q)\) ,\(\sum f(p,q)\) 是多少。
数据范围:\(1 \leq n \leq 150000\) 答案对 998244353 取模。
Two partitions of an array are considered different if the sets of indices of elements included in the subsequence p are different.
这句话可以这么理解,就算元素的值相同,只要它们在原数列中的下标不同,就算为不同的元素。
只要原列组中有一个元素的所处位置( p 或 q )不同,就视为两种划分方式不同。
思路分析
考虑暴力,我们会发现我们共需要讨论 \({2n \choose n}\) 种情况,显然不能这么算。
(上面那个是组合数公式 2n 选 n)
于是我们自然而然地想到,既然对每种划分情况行不通,我们就考虑把每个数分开来,讨论其对于答案的贡献。
通过对式子的观察,我们可以得出结论:\(x_i,y_i\) 中较大值对答案贡献为正,较小值对答案贡献为负。
首先对原数列做排序处理。
现在我们对原数列进行从小到大排序,考虑从左到右选到第 i 个数 \(a_i\) 时,之前选了 \(k\) 个数在数列 q 中,\(i-1-k\) 个数在 p 中的情形。
(为避免重复计算与讨论的麻烦,不妨假设排序时,对于值相同的元素,在 \(\{a_i\}\) 中的下标越小越小。)
于是我们知道,前 i-1 个数都比 \(a_i\) 小。
由于我们从左到右选数,我们不难看出,每选到一个数加入数列 q,这个数将从右往左地添加到 q 中。而如果是加入数列 p,这个数将被从左往右地加入 p 中。如下图:

接下来我们分析,假定我们希望将 \(a_i\) 选入 p 中,那么 \(a_i\) 对应的实际上就是 \(x_{i-1-k}\),想要这个数对答案的贡献为正,我们就需要使其对应的 \(y_{i-1-k}\) 比它小。由于我们已经将原数列排序,所以这个 \(y_{i-1-k}\) 在原数列中对应的 \(a_j\) 应有 \(j<i\) 。
而前面的数的选择我们实际上已经决定好了:我们选了 k 个数在 q 中。所以,我们必须要求这 k 个数中的某个数对于的 \(y_i\) 下标等于 \(i-1-k\) 。如下图。

显然,只有当 \(k\geq n-(i-k)+1\) 时,\(a_i\) 对答案的贡献为正。
经过简单的化简,我们得出 \(i > n\) 这样一条与 k 无关的式子。
换句话说,只要满足 \(i > n\) ,任何的将 \(a_i\) 放在 \(p\) 的情形,\(a_i\) 对答案的贡献都是正的。反之,贡献为负。
同理,假如我们考虑把 \(a_i\) 放到 q 中,同理,假如我们希望其贡献为正,那么 \(a_i\) 对应的 \(y_j\) 所对应的 \(x_j\) 所对应的 \(a_l\) 的下标应该出现在 i 之前,也就是比 \(a_i\) 小。
上面这句话可能有点绕。如下图。

显然,只有当 \(i-1-k \geq n-1-k+1\) 时,\(a_i\) 对答案的贡献为正。
化简后,我们又得到了同一条式子:\(i > n\) 。
于是,我们得出结论,无论怎么分,只要 \(i>n\) ,\(a_i\) 对答案的贡献就是正的,反之则是负的。
所以,答案就是 \({2n \choose n} \times (\sum_{i=n+1}^{2n} a_i - \sum_{i=1}^{n} a_i)\)
代码库
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
#define REG register
#define rep(i,a,b) for(REG int i=a;i<=b;i++)
const int N=3e5+5,mod=998244353;
int A[N],n; ll fac[N],ans1,ans2;
inline ll _pow(ll x,int p){
REG ll ans=1;
while(p) (p&1)&&(ans=ans*x%mod),x=x*x%mod,p>>=1;
return ans;
}
inline ll _inv(ll x){
return _pow(x,mod-2);
}
inline ll C(ll a,ll b){
return fac[a]*_inv(fac[b])%mod*_inv(fac[a-b])%mod;
}
int main(){
scanf("%d",&n);
rep(i,1,n<<1) scanf("%d",A+i);
sort(A+1,A+(n<<1)+1);
fac[0]=1;
rep(i,1,n<<1) fac[i]=fac[i-1]*i%mod;
ll temp=C(n<<1,n);
rep(i,1,n) ans1=(ans1+A[i]*temp)%mod;
rep(i,n+1,n<<1) ans2=(ans2+A[i]*temp)%mod;
printf("%lld\n",(-ans1+ans2+mod)%mod);
return 0;
}
【CF1445D】Divide and Sum 题解的更多相关文章
- Ural 1248 Sequence Sum 题解
目录 Ural 1248 Sequence Sum 题解 题意 题解 程序 Ural 1248 Sequence Sum 题解 题意 给定\(n\)个用科学计数法表示的实数\((10^{-100}\s ...
- LeetCode Continuous Subarray Sum 题解 同余前缀和 Hash表
文章目录 题意 思路 特殊情况k=0 Source Code 1 Source Code 2 题意 给定一个数组和一个整数k,返回是否存在一个长度至少为2的连续子数组的和为k的倍数. 思路 和上一篇博 ...
- Codeforces Round #680 (Div. 2, based on Moscow Team Olympiad) D. Divide and Sum (思维,数学,逆元)
题意:有一个长度为\(2n\)数组,从中选分别选\(n\)个元素出来组成两个序列\(p\)和\(q\),(\(p\)和\(q\)中只要有任意一个元素在\(a\)的原位置不同,就算一个新的情况),选完后 ...
- Hdoj 1003.Max Sum 题解
Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum ...
- [LeetCode]Combination Sum题解(DFS)
Combination Sum Given a set of candidate numbers (C) (without duplicates) and a target number (T), f ...
- [LeetCode] Three Sum题解
Three Sum: Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? ...
- 01Two Sum题解
Tow Sum 原题概述: Given an array of integers, return indices of the two numbers such that they add up to ...
- BZOJ3155:Preprefix sum——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=3155 最朴素的想法是两棵树状数组,一个记录前缀和,一个记录前缀前缀和,但是第二个我们非常不好修改 ...
- HDU4825:Xor Sum——题解
http://acm.hdu.edu.cn/showproblem.php?pid=4825 Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含 ...
随机推荐
- springmvc 源码分析(二)-- DiapartcherServlet核心调用流程分析
测试环境搭建: 本次搭建是基于springboot来实现的,代码在码云的链接:https://gitee.com/yangxioahui/thymeleaf.git 项目结构代码如下: 一: cont ...
- Spring Environment对象获取属性
String[] activeProfiles = env.getActiveProfiles();//获取当前是启用哪一个个配置文件 System.out.println(Arrays.toStri ...
- Spring Boot 第三弹,一文带你了解日志如何配置?
前言 日志通常不会在需求阶段作为一个功能单独提出来,也不会在产品方案中看到它的细节.但是,这丝毫不影响它在任何一个系统中的重要的地位. 今天就来介绍一下Spring Boot中的日志如何配置. Spr ...
- 055 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 02 数组的概念
055 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 02 数组的概念 本文知识点:数组的概念 数组的声明创建.初始化 在学习数组的声明创建.初始化前,我们可以和之 ...
- #error: Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]
转载:https://www.cnblogs.com/cvwyh/p/10570920.html 错误 在使用VS编译文件时出现了如下错误: #error: Building MFC applicat ...
- K-DTree入门
\(K-D Tree\),一种用来维护\(K\)维数据的数据结构.常用于维护各种高维的数据,或者是邻近搜索等.从另一种意义上说,实际上就是高维的二叉搜索树.对于一些常见的问题,如\(k\)远点对.三位 ...
- 腾讯云服务器,使用xshell ssh秘钥登录的时候报错:所选的用户密钥未在远程主机上注册
1.背景 新买了台腾讯云服务器,在腾讯云控制台新建了SSH私钥,然后下载到本地. 在本地使用xshell工具,导入下载好的私钥进行登录,报错:所选的用户密钥未在远程主机上注册 2.解决方案 在确定选择 ...
- 《流畅的Python》 第一部分 序章 【数据模型】
流畅的Python 致Marta,用我全心全意的爱 第一部分 序幕 第一章 Python数据模型 特殊方法 定义: Python解释器碰到特殊句法时,使用特殊方法激活对象的基本操作,例如python语 ...
- chrome(谷歌)登录失败解决方案
相信有很多小伙伴和我一样,同步chrome的收藏夹,这样也便于随时可以查看自己收藏的网址.但是同步文件,必须先要登录chrome账号,登录chrome账号时,总是会报黄页,或者一直加载不出来.接下来, ...
- 【Luogu】P3369 【模板】普通平衡树(树状数组)
P3369 [模板]普通平衡树(树状数组) 一.树状数组 树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构. ...