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

排列组合初步

时间:2024-12-31 20:53:08浏览次数:9  
标签:frac dbinom int inv 元素 初步 逆元 排列组合

排列组合初步

1. 公式部分

  1. 排列数

从\(n\)个不同元素中任取\(m\)(\(m\leq n\),
,\(m\)和\(n\)均为自然数)个元素组成一个排列。

排列数公式如下:

\(A_{n}^{m}= \frac{n!}{(n-m)!}\)

理解:第一个位子有\(n\)个选择,第二个位子有\(n-1\)个选择,以此类推,第\(m\)个有\(n-m+1\)个选择,于是得到:

\(A_{n}^{m}=n(n-1)(n-2) \cdots (n-m+1)= \frac{n!}{(n-m)!}\)

显然,\(A_{n}^{n}=n!\)。

  1. 组合数

从n个不同的元素中,任选\(m\leq n\)个元素组成一个集和,叫做从 $n \(个不同元素中取出\) m $个元素的一个组合;

从 $n \(个不同元素中取出\)m \leq n$ 个元素的所有组合的个数,叫做从$ n$ 个不同元素中取出$ m $个元素的组合数,用符号 $\dbinom{n}{m} \(来表示,及\)C_{n}^{m}$。

组合数公式如下:

\(\dbinom{n}{m} = C_{n}^{m} = \frac{A_{n}^{m}}{m!} = \frac{n!}{m!(n-m)!}\)

理解:从\(n\)个数选出\(m\)个来,不在乎顺序,据需要 $ A_{n}^{m} $ 去掉重复的。选出\(m\)个人,全排得到\(m!\),所以:\(\dbinom{n}{m} \times m! = A_{n}^{m}\)。

规定:\(m>n\)时,\(A_{n}^{m} = \dbinom{n}{m} = 0\)。

2. 隔板法(插板法)

  1. \(question 1\):
    现有$ n \(个 完全相同 的元素,要求将其分为\) k $组,保证每组至少有一个元素,一共有多少种分法?

考虑拿 $k - 1 $块板子插入到 $n \(个元素两两形成的\) n - 1 \(个空里面。 因为元素是完全相同的,所以答案就是 \)\dbinom{n - 1}{k - 1}$。

本质是求 $x_1+x_2+\cdots+x_k=n $的正整数解的组数。

  1. \(question 2\):

显然此时没法直接插板了,因为有可能出现很多块板子插到一个空里面的情况,非常不好计算。

我们考虑创造条件转化成有限制的问题一,先借$ k \(个元素过来,在这\) n + k \(个元素形成的\) n + k - 1 $个空里面插板,答案为

\(\binom{n + k - 1}{k - 1} = \binom{n + k - 1}{n}\)
虽然不是直接求的原问题,但这个式子就是原问题的答案,可以这么理解:

开头我们借来了$ k $个元素,用于保证每组至少有一个元素,插完板之后再把这 k 个借来的元素从 k 组里面拿走。因为元素是相同的,所以转化过的情况和转化前的情况可以一一对应,答案也就是相等的。

由此可以推导出插板法的公式:
\(\dbinom{n + k - 1}{n}\)。

本质是求$ x_1+x_2+\cdots+x_k=n $的非负整数解的组数(即要求 $ x_i \ge 0 $ )。

3. 线性乘法逆元求组合数

逆元

线性求\(1 \sim n\)的逆元

首先,可以显然得到 $ inv_{1} = 1\((\)inv$表示逆元)。

对于任意模数\(p\),有 $ p=k \times i + r $(\(0 \leq r<i\))

此时易得:

\(k\times i+r \equiv 0(mod \ \ p )\)

两边同乘上\(i^{-1} \cdot r^{-1}\),并进行移项:

$ \Rightarrow$ \(i^{-1} \equiv -k \times r^{-1} (mod \ \ p)\)

显然\(r^{-1}\)会先得到。所以:

\(inv_{i}=-\lfloor \frac{p}{i} \rfloor \times inv_{p \ \ mod \ \ i}\)。

于是得到:

inv[1]=1;
for(int i=2;i<=6e6;i++)
   inv[i]=(p-p/i)*inv[p%i]%p;

组合数

质数模数求法

$ \dbinom{n}{m}=\frac{n!}{m!(n-m)!}$。

这么好看的式子,显然在模意义可以拆成上下两个 ,上面的直接求取,下面的求逆元就搞定了。

\(O(n)\)预处理逆元和阶乘后,\(O(1)\)计算答案。

code:

线性求阶乘。

fac[0]=1;
for(int i=1;i<=6e6;i++)
    fac[i]=fac[i-1]*i%p;

线性求逆元。

inv[1]=1;
for(int i=2;i<=6e6;i++)
    inv[i]=(p-p/i)*inv[p%i]%p;

线性求阶乘逆元。

ifac[0]=1;
for(int i=1;i<=6e6;i++)
    ifac[i]=ifac[i-1]*inv[i]%p;

组合数计数。

int C(int a,int b)
{
    if(a==b)return 1;
    if(a<b||b<0) return 0;
    return fac[a]*ifac[a-b]%p*ifac[m]%p;
}

参考1

参考2:Oi-Wiki

待续

1. 乘法逆元求组合数(快速幂版)

2. Lucas定理求组合数

标签:frac,dbinom,int,inv,元素,初步,逆元,排列组合
From: https://www.cnblogs.com/qc0817/p/18644770

相关文章

  • ai编程助手cursor初步使用体验
    一前言前面介绍了通义灵码等国内ai编程助手,这一篇写写国外的。cursor是一款ai编程助手,因为他包含ChaGpt4和Claude3.5等先进的ai大模型来辅助编成。同时它又是一个像vscode的代码编辑器,它基于VSCode修改而来,如果平常使用VSCode进行开发,那么可以非常便捷地迁移过到cursor。简......
  • 【SpringCloud】7.Spring Cloud Alibaba 初步了解
    前面,我们学习了SpringCloud微服务解决方案:服务注册与发现、分布式配置管理:Consul服务调用和负载均衡:LoadBalancer、OpenFeign服务熔断与降级:Resilience4J分布式链路追踪:Micrometer服务网关:gateway总的来说,微服务的学习已经打通。不过,我们还需要学习SpringCloudAliba......
  • 《Vue进阶教程》第三十一课:ref的初步实现
     往期内容:《Vue进阶教程》第二十课:lazy懒执行《Vue进阶教程》第二十一课:支持缓存《Vue进阶教程》第二十二课:自定义更新(调度器)《Vue进阶教程》第二十三课:渲染计算属性的结果《Vue进阶教程》第二十四课:优化《Vue进阶教程》第二十五课:watch基本概念《Vue进阶教程》第二......
  • Splay初步
    更好的阅读体验?前言前置知识:二叉搜索树其实Splay的实现蛮多的,如果真的要能懂的话建议自己画图理解。加油。基础操作准备操作我们先把节点要维护的先定义出来。子树大小节点的权值左儿子右儿子父亲sizevalch[0]ch[1]fastructnode{intsize,val,......
  • 指针初步 - 指针概念、基本操作
    引言指针是C++中一个非常强大且灵活的特性,它允许程序员直接操作内存地址。通过指针,可以实现动态内存分配、数组和字符串操作、函数参数传递等功能。然而,指针也是C++中最容易出错的部分之一,因此理解指针的概念和正确使用指针是非常重要的。本文将详细介绍指针的基本概念和操作......
  • 记一个itertools排列组合和列表随机排序的例子
    朋友不知道哪里弄来了一长串单词列表,一定要搞个单词不重复的组合。那么这个时候我们就可以想到读书时所学的排列组合知识了,而这个在Python中可以怎么实现呢?我记录如下:使用itertools模块实现排列组合在Python中,排列组合可以通过itertools模块来实现。以下是两个主要函......
  • 某220kV降压变电站电气部分初步设计
    摘要0关键词:变电所;主接线;变压器;继电保护0前言51设计内容及要求61.1设计的原始资料及依据6(1)概述6(2)所址地理及气象条件6(3)本设计中各级电压侧年最大负荷利用小时数为:6(6)系统情况6(7)设计内容61.2负荷统计61.2.1站用复合61.2.2110kV负荷6......
  • 数智化医院分布式计算框架融合人工智能方向初步实现与能力转换浅析
    人工智能中心计算机一、引言1.1研究背景与意义近年来,人工智能(ArtificialIntelligence,AI)与大数据技术的迅猛发展为医疗行业带来了前所未有的变革机遇。医疗领域积累了海量的数据,如电子病历(ElectronicMedicalRecord,EMR)、医学影像、临床检验数据以及基因数据等。这些数......
  • 初步学习指针小作业
    一、初识指针的概念在C语言中,指针是一种变量,它存储的是另一个变量的内存地址。 就好像你有很多信箱(变量),每个信箱都有一个编号(内存地址)。指针就是一个小纸条,上面写着某个信箱的编号,通过这个编号就能找到对应的信箱。 例如,有一个变量 inta=10; ,可以定义一个指针变量......
  • c++领域展开第四幕——类和对象(上篇收尾 this指针、c++和c语言的初步对比)超详细!!!!
    文章目录前言一、this指针二、c++和c语言的初步对比总结前言上篇我们初步学习了类的基本概念以及实例化今天我们来学习类的构造以及析构还有类的默认成员函数,类和对象这一部分都会有点难跟着我一起来吧一、this指针Date类中有Init与Print两个成员函数,函......