首页 > 其他分享 >简单组合计数

简单组合计数

时间:2022-11-30 22:35:46浏览次数:35  
标签:frac 组合 int bmod 多重集 计数 简单 prod sum

简单组合计数

组合计数基础

几个原理:

1.加法原理:若完成一件事有\(n\)类不同的方法,第\(i\)类方法有\(a_i\)种方法,且这些方法互不重合则完成这件事共有\(\sum_{i=1}^na_i\)种方法

2.乘法原理:若完成一件事有\(n\)个不同的步骤,每个步骤有\(a_i\)种完成方法,且互不干扰,则完成该件事共有\(\prod_{i=1}^na_i\)种方法

几个定义:

1.排列数:从\(n\)个不同的数里依次 取出\(m\)个,产生的不同排列数量为:

\[A_n^m(\text{或}P_n^m)=\prod_{i=n-m+1}^n i=\frac{n!}{(n-m)!} \]

注意是\(m\)在上

2.组合数:从\(n\)个不同的数里取出\(m\)个组成一个集合(不考虑顺序,只要元素到位),产生的不同集合数量为:

\[C_n^m=\frac{A_n^m}{m!}=\frac{n!}{m!(n-m)!} \]

性质:

1.\(C_n^m=C_n^{n-m}\)

2.\(C_n^m=C_{n-1}^m+C_{n-1}^{m-1}\)      重要

3.\(\sum_{i=0}^nC_n^i=2^n\)

4.\(\sum_{k=0}^n(-1)^kC_n^k=0\)

5.\(C_{m+n}^k=\sum_{j=0}^k(C_m^{k-j}\times C_n^j)\)

6.\(C^{k+1}_ {n+1} =\sum_{i=k}^nC_i^k\)

7.Lucas定理:若\(p\)是质数,则对于任意整数\(1\le m\le n\)有

\[C_n^m\equiv C^{m \bmod p}_ {n\bmod p}\times C^{\lfloor \frac{m}{p} \rfloor}_ {\lfloor \frac{n}{p} \rfloor} (\bmod p) \]

这个注意代码实现的时候得递归实现

二项式定理

\[(a+b)^n=\sum_{k=0}^nC_n^ka^kb^{n-k} \]

多项式定理

设\(n\)是正整数,则对于所有的\(x_i\) \((i\in [1,t])\)有

\[(\sum_{i=1}^tx_i)^n=\sum_{\left(\sum_{p=1}^tn_p\right)=n}\left(\frac{n!}{\prod_{k=1}^t(n_k!)}\right)\prod_{j=1}^tx_j^{n_j} \]

这里把\(n_i\)的所有组合枚举出来即可

多重集的排列数

多重集是允许包含重复元素的集合,设集合\(\mathbb{S}={\lbrace n_1·a_1,n_2·a_2,n_3·a_3…n_k·a_k\rbrace}\)是由\(n_1\)个\(a_1\)……组成的多重集,\(n=\sum_{i=1}^kn_i\)则它的全排列个数为:

\[\frac{n!}{\prod_{k=1}^m(n_k!)} \]

多重集的组合数

设集合\(\mathbb{S}={\lbrace n_1·a_1,n_2·a_2,n_3·a_3…n_k·a_k\rbrace}\)是由\(n_1\)个\(a_1\)……组成的多重集,\(n=\sum_{i=1}^kn_i\)
则从该集合中选出\(r(r\le n)\)个数组成的不同的多重集数量为:

\[C_{k+r-1}^{k-1}-\sum_{i=1}^kC^{k-1}_ {k+r-n_i-2}+\sum_{1\le i<j \le n}C_{k+r-n_i-n_j-2}^{k-1}-…+(-1)^kC_{k+r-n-k-1}^{k-1} \]

Catlan数

定义

\[Cat_n=C_{2n}^n-C_{2n}^{n-1}=\frac{C_{2n}^n}{n+1} \]

与其有关的问题:

1.给定n个左括号和n个右括号组成合法的括号序列的个数为\(Cat_n\)

2.\(1\sim n\)依次进栈,合法的出栈序列个数为\(Cat_n\)

3.n个节点组成的不同二叉树的数量是\(Cat_n\)

4.在平面直角坐标系中每一步只能向上或者向右走,从点\((0,0)\)到点\((n,n)\)并且除了两个端点之外路线上没有一个点经过直线y=x,这样的路径条数一共有\(2Cat_{n-1}\)

几个结论:

1.将一个长度为n的环变作n个自环至少要将节点交换n-1次

2.设\(F_n\)表示用最少步骤将一个长度为n的环变作n个自环的操作方案数,有:\(F_n=n^{n-2}\)

3.遇到序列上的错位,需要交换位置还原的问题可以往图论方向想

exlucas

用途:快速求出以下式子的值(p不一定是质数)

\[C_n^m \bmod p \]

遇到这种情况,我们可以将p进行算术基本定理的质因数分解。设\(p=\prod_{i=1}^kp_i^{c_i}\),我们设\(a_i=C_n^m \bmod p_i^{c_i}\)

这样我们就把问题简化成了:

\[\left\{ \begin{aligned} x \bmod& p_1^{c_1}=a_1 \\ x \bmod& p_2^{c_2}=a_2 \\ x \bmod& p_3^{c_3}=a_3 \\ &\vdots \\ x \bmod& p_k^{c_k}=a_k \\ \end{aligned} \right. \]

这个一次同余式组直接用中国剩余定理\(CRT\)求即可

问题在于如何求出\(C_n^m \bmod p_i^{c_i}\)

先来看简化版扩展卢卡斯:

古代猪文

题意:给定整数\(n,q(n,q\le 10^9)\)计算

\[q^{\sum_{d|n}C_n^d } \bmod 999911659 \]

因为999911659是一个质数,由扩欧得:

原式等价于

\[q^{\sum_{d|n}C_n^d \bmod 999911658} \bmod 999911659 \]

所以本题关键在于计算\(\sum_{d|n}C_n^d \bmod 999911658\)

按照扩展卢卡斯的思路,我们将999911658分解质因数发现:\(999911658=2\times 3\times 4679 \times 35617\)

我们枚举n的约数d,分成四个,运用Lucas定理分别计算组合数\(C_n^d\)对这四个质因数的模,求出\(\sum_{d|n}C_n^d\)模这四个质数的值,记作\(a_1,a_2,a_3,a_4\)

当然对于质数的逆元啥的自己预处理一下就可以

现在我们的问题就是求解同余方程组

\[\left\{ \begin{aligned} x \bmod& 2&=&a_1 \\ x \bmod& 3&=&a_2 \\ x \bmod& 4679&=&a_3 \\ x \bmod& 35617&=&a_4 \\ \end{aligned} \right. \]

然后用快速幂进行计算即可

#define int long long 
int mod=999911659,p[4]={2,3,4679,35617},n,m,cnt,ans,q;
int ys[40000],jc[40000],a[4],x,y,t;
int power(int a,int b,int p){
    int ans=1;
    while(b){
    	if(b&1)ans=ans*a%p;
    	a=a*a%p;
    	b>>=1;
	}
    return ans;
}
int C(int n,int m,int p){
    return n<m?0:jc[n]*power(jc[m]*jc[n-m],p-2,p)%p;
}
int lucas(int n,int m,int p){
    return m?C(n%p,m%p,p)*lucas(n/p,m/p,p)%p:1;
}
int exgcd(int a,int b,int &x,int &y){
    if(!b){
    	x=1,y=0;
    	return a;
	}
	int d=exgcd(b,a%b,x,y);
	int t=x;
	x=y,y=t-(a/b)*y;
	return d;
}
signed main(){
    scanf("%lld%lld",&n,&q);
    if(q%mod==0){
        puts("0");
        return 0;
    }
    jc[0]=1;
    m=sqrt(n);
    for(int i=1;i<=m;i++){
        if(n%i==0){
			ys[++cnt]=i,ys[++cnt]=n/i;
		}
	}
    cnt-=ys[cnt-1]==ys[cnt];
    for(int i=0;i<4;i++){
        for(int j=1;j<p[i];j++){
			jc[j]=jc[j-1]*j%p[i];
		}
        for(int j=1;j<=cnt;j++){
			a[i]=(a[i]+lucas(n,ys[j],p[i]))%p[i];
		}
        exgcd((mod-1)/p[i],p[i],x,y);
        ans=(ans+a[i]*(x%p[i]+p[i])*(mod-1)/p[i])%(mod-1);
    }
    printf("%lld\n",power(q,ans,mod));
    return 0;
}
 

这也就是所有的\(c_i=1\)时的简化情况

标签:frac,组合,int,bmod,多重集,计数,简单,prod,sum
From: https://www.cnblogs.com/oierpyt/p/16939975.html

相关文章

  • 容斥与简单莫反
    容斥与莫比乌斯函数容斥原理:介绍:设集合\(S_1\simS_n\),记\(|S_i|\)表示集合\(S_i\)的大小,设\(\cup\)表示集合的并集运算,\(\cap\)表示集合的交集运算,则\[\left|\bigcup_......
  • 进程与线程的一个简单解释
    进程​(process)和线程(thread)是操作系统的基本概念,但是它们比较抽象,不容易掌握。最近,我读到一篇材料,发现有一个很好的类比,可以把它们解释地清晰易懂。1.计算机的核心是CPU,它承......
  • TS的优点,简单版
    #TS的优势+更早发现错误,提高开发效率+随时随地提示,增强开发体验+强大类型系统,代码可维护性更好,重构代码更容易+类型推断机制,减少不必要类型注解,让代码更简单+v......
  • 简单快捷又实用,SmartRooms智能会议室全都能满足​
    简单快捷又实用,SmartRooms智能会议室全都能满足​近年来,混合办公日益成为职场人的常态,企业也纷纷上马各类视频会议硬件终端,然而线上线下、内外部会议割裂,各品牌软硬件孤岛的......
  • 华为云分布式全系列产品组合,帮助企业轻松上云​
    我们知道,云计算技术从诞生之初就是为了解决传统的计算难题,以服务为中心的架构,让企业获得了“云”时代所带来的诸多便利。随着云计算、大数据等技术的不断发展,传统架构所带......
  • BUUCTF-PWN-前五页简单回顾
    学pwn到现在快三个月了,在BUU上做了前五页共160题,不能把刷过的题的技巧都给忘了,再做一遍还不是得心应手的题,同时堆题很灵活,要多总结才能举一反三。现在写下刚开始学的......
  • 一个简单的ssm案例之Mybatis框架搭建
    1、修改AccountDaopackagecom.cnstrong.dao;importcom.cnstrong.domain.Account;importorg.apache.ibatis.annotations.Insert;importorg.apache.ibatis.annotations.Se......
  • 一个简单的ssm案例之spring整合mybatis
    把生成的代理对象存到ioc容器中,service就可以拿到代理对象并注入,就可以调用dao中的方法。1、修改applicationContext.xml<?xmlversion="1.0"encoding="UTF-8"?><beansxm......
  • 一个简单的ssm整合案例之spring整合mybatis配置事务
    1、修改applicationContext.xml为:<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.......
  • Springboot实现HTML表单from简单的接收信息
    HTML<from>元素from可向Web服务器提交请求普遍格式:<fromaction="服务器地址"method="请求方式"enctype="数据格式"><inputtype="submit"value="Test按......