首页 > 其他分享 >CF1999F.Expected Median 题解

CF1999F.Expected Median 题解

时间:2024-08-09 21:28:24浏览次数:10  
标签:cnt frac CF1999F 题解 ll ret Expected return mod

一.前言

这是一道很有趣的数学题目,用到了逆元和组合数学,非常适合新手练手。

二.题目大意:

给出一个长度为 \(n\) 的 \(01\) 数组。找出所有长度为 \(k\) 的子序列的中位数,求出其和。

妥妥的数学题~

三.分析

首先考虑对答案的贡献。

很明显,只有 \(1\) 作为中位数时才会做出贡献,于是抛弃 \(0\) 不管。

对于 \(1\),将序列排序后最少有 \(\frac{k+1}{2}\) 个 \(1\) 时 \(1\) 才是中位数,能对答案做出贡献。

举个栗子。当 k = 5 时,构造序列如下:

\(\left\lbrace0,0,1,1,1\right\rbrace\)

很明显,中位数在第 \(3\) 个位置,即 \(\frac{5+1}{2} = 3\),那么,此序列有多少个 \(1\) 呢?没错,\(5 - \frac{5+1}{2} + 1 = 3\) 个。非常好!用 \(k\) 替代数字 \(5\),\(k - \frac{k+1}{2} + 1 = \frac{k+1}{2}\)。

所以,\(1\) 个数的范围应该是 \([\frac{k+1}{2},k]\)。

这是奇数的栗子,当然,偶数也是如此,同学们可以自己尝试一下,我就不在赘述啦。其实是我懒啦。

这时,离成功仅有一步之遥。

枚举 \(1\) 的个数,考虑其为 \(i\) 时的情况。

很容易想到,从 \(1\) 的总个数里选出 \(i\) 个的方案数乘上从 \(0\) 的总个数里选出 \(k-i\) 个的方案数即可。

再对每个 \(i\) 分别计算再求和即可。

即:\(ans = \underset{i=x}{\overset{cnt}{\sum}} \binom{cnt}{i} \times \binom{n-cnt}{k-i}\)。

\(cnt\) 为 \(1\) 的总数,\(x\) 为 \(1\) 最少的个数。

最后注意组合数的合适求法以及取模。

好,这道题目就讲完了,是不是非常简单呢?

最后贴一下代码。

四.代码

#include <bits/stdc++.h>
#define ll long long
#define pii pair <int, int>
using namespace std;
const int N = 2e5 + 10;
const ll mod = 1e9 + 7;
ll a[N]; ll ans, f[N];
inline ll ppow(ll a, ll b) {
	ll ret = 1;
	while (b) {
		if (b & 1) ret = ret * a % mod;
		a = a * a % mod; b >>= 1;
	}
	return ret;
}
inline ll C(ll n, ll k) {
	if (n < k) return 0;
	if (k < 0) return 0;
	ll ret = f[n] * ppow(f[k], mod - 2) % mod;
	ret = ret * ppow(f[n - k], mod - 2) % mod;
	return ret;
}
inline void solve() {
	ll n, k; cin >> n >> k;
	ll x = (k + 1) / 2, cnt = 0;
	ans = 0;
	for (int i = 1; i <= n; ++i)
		cin >> a[i], cnt += a[i];
	for (int i = x; i <= cnt; ++i) {
		ans += C(cnt, i) * C(n - cnt, k - i) % mod;
		ans %= mod;
	}
	cout << (ans % mod) << "\n";
}
int main() {
	f[0] = 1;
	for (int i = 1; i <= N - 10; ++i)
		f[i] = f[i - 1] * i % mod;
	int T; cin >> T;
	while (T -- ) solve();
	return 0;
}

最后不要脸地求个赞。

QwQ

标签:cnt,frac,CF1999F,题解,ll,ret,Expected,return,mod
From: https://www.cnblogs.com/2026zhaoyl/p/18351526

相关文章

  • CF908G New Year and Original Order 题解
    CF908C定义\(S(n)\)为将\(n\)所有数位从小到大排序后得到的数,求\(\sum_{i=1}^{n}S(i)\)\(1\leqn\leq10^{700}\)看到这个题大部分人都会奔着数位\(dp\)的地方想但这个题的难度在于插入一个数后不好算贡献其实也挺好算的\(dp\)维护当前若干数字排完序......
  • CF641E Little Artem and Time Machine 题解
    题目传送门前置知识CDQ分治解法单点修改区间查询,但值域巨大,考虑离散化掉\(x\)。时刻\(t\)仍很大,考虑将其作为CDQ分治的第一维,然后套个CDQ分治即可,注意及时清空桶数组。代码CodeForces275382150#include<bits/stdc++.h>usingnamespacestd;#definelllonglon......
  • CF1209E2 Rotate Columns (hard version) 题解
    CF1209E2给定\(n\timesm\)的矩阵,可以对每一列进行若干次循环移位,求操作完成后每一行的最大值之和的最大值。\(1\leqn\leq12,1\leqm\leq2000\)这里\(m\)很大,但有一个很重要的性质这\(m\)列中只有最大的前\(n\)个会对答案产生贡献因此我们直接就把......
  • 【题解】ABC365(A~E)
    前四题30min切,然后T5死磕70min+几发小唐错,距离比赛结束还有16s交最后一发,AC了。目录A.LeapYear题目描述思路代码B.SecondBest题目描述思路代码C.TransportationExpenses题目描述思路代码D.AtCoderJanken3题目描述思路代码E.XorSigmaProblem题目描述思路代码A.Lea......
  • CF908E New Year and Entity Enumeration 题解
    CF908E给定\(m\),令\(M=2^m-1\)。给定\(\{0,1,\cdots,M\}\)的大小为\(n\)的子集\(T\),定义集合\(T\subseteqS\subseteq\{0,1,\cdots,M\}\)是好的当且仅当:\(a\inS\Rightarrowa\oplusM\inS\)\(a,b\inS\Rightarrowa\and\b\inS......
  • 题解:CF1209E1 Rotate Columns (easy version)
    题目传送门题意给出一个\(n\timesm\)的矩阵,我们可以对每一列进行循环位移,不限次数,最后求每一行的最大值之和。\(1\leqn\leq4,1\leqm\leq100\)思路注意到\(n\)的范围很小,那么我们也可以缩小\(m\)的范围。正确的方案显然是取整个矩阵的前\(n\)大值,并且将它......
  • CF1647F Madoka and Laziness 题解
    CF1647F给定排列\(p\),将其划分为两个单峰子序列,求两个单峰子序列的峰的组合的情况数。\(2\leqn\leq5\times10^5\)首先要注意到一个非常常见的地方:两个单峰子序列中的一个的峰值一定在整个排列\(p\)的最大值处这个非常显然,但并不注意到他的重要性,容易被忽视为......
  • 2024牛客暑期多校训练营8 I Haitang and Ranking 题解
    乱搞看到\(n=1e5\),时限3s,存在修改操作,很自然的想到根号分治。考虑按照时间分治。对每\(B\)个交换统一处理,\(B\)个交换最多有\(2B\)个元素改变状态,剩下都不变。那么只要对这\(2B\)元素内,暴力枚举,剩下的元素构建数据结构实现二维数点,平面内区间最值。因为\(a,b\)是不......
  • luogu题解:P10456 The Pilots Brothers' refrigerator【缺少 SPJ】
    思路此题题意酷似P10449.费解的开关。https://www.luogu.com.cn/problem/P10449不同之处便是状态连锁改变不同,但做法截然不同,此题是一个\(4\times4\)的矩阵。暴力枚举的复杂度是\(O(10^7)\),即\(2^{16}\times16\times16=16777216\),\(10^7\)的复杂度可以通......
  • P2901题解
    题目大意输出一张有向带权图前k短路的长度思路分析这是道k短路板子题我们可以用Astar算法来实现它OIwiki相关算法的网页简单来讲,Astar定义了一个估值函数f(x)=g(x)+h(x)g(x)表示由起点到达x点的路程(不一定是最短路),而h(x)则是终点到x点的最短路程这个估值函数可以预估从该......