恶补费马小定理和组合数

前言:我们平时遇到的组合数如果用杨辉三角型做的话,预处理的复杂度是 n 2 n^2 n2 ,遇到大一点的数据就会爆炸

我们怎么去优化呢
C ( n , k ) = n ! k ! ⋅ ( n − k ) ! m o d    mod C(n, k) = \frac{n!}{k! \cdot (n-k)!} \mod \text{mod} C(n,k)=k!⋅(n−k)!n!modmod

答案太大我们会进行取模,那么我们就可以利用费马小定理

所以我们可以对我们的分母乘积进行逆元操作

但是我们的阶乘进行预处理


我们再来看一下下面这个题目,分析我们得知,只有我们选取的 1 的个数是大于等于 k /2 +1 的,才是有价值的

所以我们可以用组合数的方法进行


题目地址


有一个易错点,我们预处理的时候,阶乘的 a 0 = 1 , 否则会出错


cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

#define int long long
// 1 2 3
const int Mod = (int)1e9 + 7;
int n, k;
const int N = (int)2e5 + 5;
int a[N];

void ini() {
	a[1] = 1; a[0] = 1;
	for (int i = 2; i < N; i++) {
		a[i] = (a[i - 1] * i) % Mod;
	}
}

int qw(int x, int p) {
	int t = 1;
	while (p) {
		if (p & 1) t = (t * x) % Mod;
		x = (x * x) % Mod;
		p >>= 1;
	}
	return t;
}

int C(int n, int k) {
	if (n < k) return 0LL;
	return (a[n] % Mod) * (qw(a[n - k] * a[k] % Mod, Mod - 2) % Mod) % Mod;
}

signed main() {
	int t; ini();
	//for (int i = 1; i <= 10; i++) cout << a[i] << endl;
	//cout << qw(2, 2);
	cin >> t;
	while (t--) {
		cin >> n >> k;
		int one = 0;
		for (int i = 1; i <= n; i++) {
			int u; cin >> u;
			if (u) one++;
		} 
		int ans = 0;
		for (int i = k / 2 + 1; i <= min(one, k); i++) {
			int t = C(one, i) * C(n - one, (k - i)) % Mod;
			ans = (ans + t) % Mod;
		}
		cout << ans << endl;
	}

}
相关推荐
Evand J12 分钟前
【PMSM例程1】永磁同步电机(PMSM)转速与转子电角度观测算法|基于扩展卡尔曼滤波(EKF)的传感器状态估计与误差。附下载链接
算法·电机·1024程序员节·卡尔曼滤波
guo_wen_qiang13 分钟前
二叉树的层序遍历-使用双端队列Deque
算法·leetcode·1024程序员节
爱读书的小胖29 分钟前
LeetCode 55 跳跃游戏 C 语言解题分析
c语言·数据结构·算法·leetcode·1024程序员节
CCblandy31 分钟前
前缀缓存命中率不靠引擎靠排列:本机仿真 3 轮,易变字段放开头 98.0%→0.0%
人工智能·python·算法·自然语言处理·性能优化
上班摸鱼下班游戏35 分钟前
Unity 仿生智能算法 从蚁群算法 开始
算法·unity·游戏引擎
pipixia200331 小时前
C++ 面试高频:namespace 的 6 个知识点,从 using 到匿名命名空间
c语言·学习·算法·嵌入式·命名空间·c++面试·匿名命名空间
Navigator_Z2 小时前
LeetCode //C - 1300. Sum of Mutated Array Closest to Target
c语言·算法·leetcode
SZYSK2 小时前
鸿蒙人脸识别算法放在终端里:和外挂授权 SDK 差在排障路径
物联网·算法·华为·harmonyos
凯瑟琳.奥古斯特2 小时前
力扣1016高效解法:剪枝优化技巧
开发语言·c++·算法·leetcode·职场和发展
xiangyun613 小时前
C++ priority_queue 底层:手撕二叉堆与 Top K 问题
c++·算法·面试·stl·1024程序员节