首页 > 其他分享 >排列组合

排列组合

时间:2025-01-10 11:45:31浏览次数:1  
标签:return int res LL ++ 排列组合 primes

、递推法求组合数 —— 模板题 AcWing 885. 求组合数 I
// c[a][b] 表示从a个苹果中选b个的方案数
for (int i = 0; i < N; i ++ )
for (int j = 0; j <= i; j ++ )
if (!j) c[i][j] = 1;
else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;

、通过预处理逆元的方式求组合数 —— 模板题 AcWing 886. 求组合数 II
首先预处理出所有阶乘取模的余数fact[N],以及所有阶乘取模的逆元infact[N]
如果取模的数是质数,可以用费马小定理求逆元
int qmi(int a, int k, int p) // 快速幂模板
{
int res = 1;
while (k)
{
if (k & 1) res = (LL)res * a % p;
a = (LL)a * a % p;
k >>= 1;
}
return res;
}

// 预处理阶乘的余数和阶乘逆元的余数
fact[0] = infact[0] = 1;
for (int i = 1; i < N; i ++ )
{
fact[i] = (LL)fact[i - 1] * i % mod;
infact[i] = (LL)infact[i - 1] * qmi(i, mod - 2, mod) % mod;
}

、Lucas定理 —— 模板题 AcWing 887. 求组合数 III
若p是质数,则对于任意整数 1 <= m <= n,有:
C(n, m) = C(n % p, m % p) * C(n / p, m / p) (mod p)

int qmi(int a, int k, int p) // 快速幂模板
{
int res = 1 % p;
while (k)
{
if (k & 1) res = (LL)res * a % p;
a = (LL)a * a % p;
k >>= 1;
}
return res;
}

int C(int a, int b, int p) // 通过定理求组合数C(a, b)
{
if (a < b) return 0;

LL x = 1, y = 1;  // x是分子,y是分母
for (int i = a, j = 1; j <= b; i --, j ++ )
{
    x = (LL)x * i % p;
    y = (LL) y * j % p;
}

return x * (LL)qmi(y, p - 2, p) % p;

}

int lucas(LL a, LL b, int p)
{
if (a < p && b < p) return C(a, b, p);
return (LL)C(a % p, b % p, p) * lucas(a / p, b / p, p) % p;
}

、分解质因数法求组合数 —— 模板题 AcWing 888. 求组合数 IV
当我们需要求出组合数的真实值,而非对某个数的余数时,分解质因数的方式比较好用:
1. 筛法求出范围内的所有质数
2. 通过 C(a, b) = a! / b! / (a - b)! 这个公式求出每个质因子的次数。 n! 中p的次数是 n / p + n / p^2 + n / p^3 + ...
3. 用高精度乘法将所有质因子相乘

int primes[N], cnt; // 存储所有质数
int sum[N]; // 存储每个质数的次数
bool st[N]; // 存储每个数是否已被筛掉

void get_primes(int n) // 线性筛法求素数
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i]) primes[cnt ++ ] = i;
for (int j = 0; primes[j] <= n / i; j ++ )
{
st[primes[j] * i] = true;
if (i % primes[j] == 0) break;
}
}
}

int get(int n, int p) // 求n!中的次数
{
int res = 0;
while (n)
{
res += n / p;
n /= p;
}
return res;
}

vector mul(vector a, int b) // 高精度乘低精度模板
{
vector c;
int t = 0;
for (int i = 0; i < a.size(); i ++ )
{
t += a[i] * b;
c.push_back(t % 10);
t /= 10;
}

while (t)
{
    c.push_back(t % 10);
    t /= 10;
}

return c;

}

get_primes(a); // 预处理范围内的所有质数

for (int i = 0; i < cnt; i ++ ) // 求每个质因数的次数
{
int p = primes[i];
sum[i] = get(a, p) - get(b, p) - get(a - b, p);
}

vector res;
res.push_back(1);

for (int i = 0; i < cnt; i ++ ) // 用高精度乘法将所有质因子相乘
for (int j = 0; j < sum[i]; j ++ )
res = mul(res, primes[i]);

标签:return,int,res,LL,++,排列组合,primes
From: https://www.cnblogs.com/xtxm/p/18663677

相关文章

  • 百丽宫22年真题题解——最短路径(排列组合法)
    #include<stdio.h>unsignedlonglonghigh;unsignedlonglonglow;unsignedlonglongfac(intn,intm){unsignedlonglongi,f=1;if(m!=1){for(i=n;i>=n-m+1;i--){f=f*i;}returnf;}elseif(m......
  • 排列组合初步
    排列组合初步1.公式部分排列数从\(n\)个不同元素中任取\(m\)(\(m\leqn\),,\(m\)和\(n\)均为自然数)个元素组成一个排列。排列数公式如下:\(A_{n}^{m}=\frac{n!}{(n-m)!}\)理解:第一个位子有\(n\)个选择,第二个位子有\(n-1\)个选择,以此类推,第\(m\)个有\(n-m+1\)个选择,于是得......
  • 记一个itertools排列组合和列表随机排序的例子
    朋友不知道哪里弄来了一长串单词列表,一定要搞个单词不重复的组合。那么这个时候我们就可以想到读书时所学的排列组合知识了,而这个在Python中可以怎么实现呢?我记录如下:使用itertools模块实现排列组合在Python中,排列组合可以通过itertools模块来实现。以下是两个主要函......
  • 排列组合(一)
    目录排列组合示例题目题目答案与解析开学后的第一篇博文,太不容易了。。。。。今后我会做更多关于我要打的比赛要考的一些知识,也方便自己回顾。最后有很多例题给大家练练手哦。前言排列组合是CCF(中国计算机学会(ChinaComputerFederation),大家可以去看看它的官网:http......
  • 排列组合:公式及推导
    排列组合:公式及推导引入定义:排列:从指定个数的元素中取出指定个数的元素进行排序;(考虑元素的顺序)组合:从给定个数的元素中仅仅取出指定个数的元素;(不考虑元素的顺序)加法&乘法原理加法原理:完成一个工程可以有\(n\)类办法,\(a_i(i\in[1,n])\)代表第\(i\)类方法的数目。则......
  • 一个小学生蒟蒻对简单排列组合的认知和了解
    一个小学生蒟蒻对简单排列组合的认知和了解呃呃呃呃呃....可能写的有点不咋好...呃呃呃神马是排列组合神马是排列组合呢?我感觉我也不太清楚排列组合是组合数学中的基础。排列就是指从给定个数的元素中取出指定个数的元素进行排序;组合则是指从给定个数的元素中仅仅取出指定个......
  • 一个蒟蒻小学生尝试学习高级排列组合
    一个蒟蒻小学生尝试学习高级排列组合呃呃呃呃呃呃,我不咋会写,如有不对的地方欢迎纠正紧接上文我们已经了解了基础的排列组合,我们可以接着往下学习排列组合的变种了.1.排列组合的变种1-1.多重集的排列数+多重组合数大家一定要区分多重组合数与多重集的组合数!两者是完......
  • 笔记——排列组合
    蓝月の笔记——排列组合篇摘要万恶的数学!Part1加乘原理小学奥数内容加法原理:当多个方案并列(即互不影响)时,总方案数为各个方案数之和例:共有\(k\)种交通工具可以从A地到B地,第\(i\)种交通工具有\(a_i\)班次,那么从A地到B地的总方案数为\(\sum_{1\lei\lek}a_i\)乘......
  • 可用于机器学习的排列组合枚举算法含passcal - c shap-c源码
    可用于机器学习的排列组合枚举算法含passcal-cshap-c源码1机器学习和数据挖掘• 特征选择:在机器学习中,需要从多个特征中选择最有价值的组合。通过枚举不同的特征组合,可以找到最佳的特征集合。• 超参数优化:在训练模型时,需要调整多个超参数。通过枚举不同的超参数组......
  • 递归示例-指定数字以内的所有排列组合(Base)
    指定数字以内的所有排列组合:定义名称版:=pmtB(指定数字)=LAMBDA(x,IF(x=1,1,VSTACK(pmtB(x-1),SUBSTITUTE(BASE(SEQUENCE(x^x)-1,x,x),0,x))))不定义名称版:=LET(fx,LAMBDA(npmtB,x,IF(x=1,1,VSTACK(npmtB(npmtB,x-1),SUBSTITUTE(BASE(SEQUENCE(x^x)-1,x,x),0,x)))),fx......