蒟蒻 的 【数论】 博客

数论!!!(是我配不上的·东西QWQ…)

质数

定义:若一个正整数a无法被除了1和它本身以外的任何自然数整除,则乘该数为质数(或素数),否则称该数为合数。

质数的判定

经典算法:试除法

若一个数n为合数,那么存在一个能整除n的数T, 其中 2<=T<= n \sqrt{n} n

证:n可被分解为: T * q,设T为较小的那个数。若T> n \sqrt{n} n ,则p> n \sqrt{n} n ,那么T * p显然大于n。

所以上述说法成立。

所以,试除法便是扫描2~ n \sqrt{n} n 的所有整数,判断其中是否存在一个数能够整除n,若不存在,则n为质数。

代码如下:

#include<bits/stdc++.h>
using namespace std;
int n;
int main()
{
	cin>>n;
	for(int i=1;i<=sqrt(n);i++)
	{
		if(!n%i) 
		{
		 flag=0;//n为合数
		 break;
		}
	}
	if(flag) 
	printf(“n为质数”);
	return 0}

质数的筛选

Eratosthenes筛

Eratosthenes筛基于这样的想法:任意整数的倍数:2x,3x,4x…都不是质数。

我们可以从2开始,把它的倍数(<=n)都标记为合数。这样,从小到大依次扫描,若一个数未被标记,则其为质数(因为它与小于它的数都互质)。

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6;
int n,v[N],prime[N],cnt;
int main()
{
	scanf("%d",&n);
	for(int i=2;i<=n;i++)
	{
		if(v[i]) continue;
		prime[++cnt]=i;
		for(int j=i;j<=n;j+=i)
		v[i*j]=1;
	}
	return 0;
}

更为实用的质数筛:

线性筛法(欧拉筛)

我们从Eratosthenes筛的代码中可以知道,其时间复杂度为: O(n * log log n),接近线性,已经十分实用了。

但是,相比较于真正线性的欧拉筛,Eratosthenes筛还是较为逊色。

欧拉筛的本质便是:让每一个合数都被它的最小质因子标记,这样,便能以线性(即O(n))的时间复杂度来筛出质数。

代码如下:

int n,prime[maxn],cnt,v[n];  
void oula()
{            
    v[0] = v[1] = 1; 
    for (int i = 2; i <= n; i++) 
    {
        if (!v[i]) 
        {         
        	prime[++cnt]=i;
            for (int j = 1; j < cnt; j ++) 
            { 
            	v[i*prime[j]]=1;
                if(!i%prime[j]) 
                break;
//i%prime[j]==0,即代表i的质因数包含prime[j],因为欧拉筛的本质是使每个数的最小质因子标记它,因为prime[j+1]>prime[j],且i中包含prime[j],所以直接break
            }
        }
    }
}

顺便提一嘴:欧拉筛也可以求1~n的欧拉函数值。

质因数分解

任何一个数都能唯一分解为有限个质数的乘积,可写做:

N= p 1 c 1 p 2 c 2 p 3 c 3 {p_1}^{c^1} {p_2}^{c^2} {p_3}^{c^3} p1c1p2c2p3c3 p m c m {p_m}^{c^m} pmcm

其中c都是正整数,p都是质数,且满足:p1<p2<p3…<pm。

若要将一个数质因数分解,目前为止,除了试除法,也没有其它特别优秀的算法了。

附上代码:

``

#include<bits/stdc++.h>
using namespace std;
int n,p[100000],c[100000],cnt;
int main()
{
	for(int i=2;i<=sqrt(n);i++)
	{
		if(n%i==0) p[++cnt]=i,c[cnt]=0;
		while(n%i==0)
		{
			n/=i;
			c[cnt]++;
		}
	}
	if(n>1) p[++cnt]=n,c[cnt]=1;//n中包含大于sqrt(n)的质因子,且最多只有一个
}

约数

定义

若整数n除以整数d的余数为0,即d能整除n,则称d是n的约数,n是d的倍数。记为: d|n

算数基本定理的推论:

对于一个数N,将其质因子分解, N= p 1 c 1 p 2 c 2 p 3 c 3 {p_1}^{c^1} {p_2}^{c^2} {p_3}^{c^3} p1c1p2c2p3c3 p m c m {p_m}^{c^m} pmcm

N的正约数个数为: ∏ i = 1 m \prod\limits^m_{i=1} i=1m(c[i] + 1)=(c[1]+1) * (c[2]+1) * (c[3]+1)…*(c[m]+1)。

证:对于p1,我们可以取1, p 1 p1 p1, p 1 2 p1^2 p12, p 1 3 p1^3 p13 p 1 c 1 p1^{c1} p1c1,共有c1+1次;对于p2,我们可以取c2+1次…

根据乘法原理,我们可以得到以上式子。

N的所有正约数的和为: ∏ i = 1 m \prod\limits^m_{i=1} i=1m( ∑ j = 0 c [ i ] \sum\limits^{c[i]}_{j=0} j=0c[i]( p [ i ] j {p[i]}^j p[i]j) )=(1+p1+ p 1 2 {p1}^2 p12+ p 1 3 {p1}^3 p13+… p 1 c 1 {p1}^{c1} p1c1) * (1+p2+ p 2 2 {p2}^2 p22+ p 2 3 {p2}^3 p23+… p 2 c 2 {p2}^{c2} p2c2)*…

证:你可以把它转化为这个问题,p1 ~ pn中每个都有n+1种选择,每次从p1 ~ pn中取出一种,构成一个组合,然后将所有组合相加,简化就得到上述式子了。

欧几里得算法

**gcd(a,b)=gcd(b,a%b) ** 。

这个可以这么来证:

设e=gcd(a,b),a=k1 * e,b=k2 * e。

我们首先来证明:gcd(a,b)=gcd(b,a-b)。

a-b=(k1 - k2) * e,b=k2 * e。如果能证明 k2 与 k1-k2互质,那么 a-b便与b互质。

我们可以用假设法来证明:

因为 k1 与 k2 互质,所以 gcd(k1 , k2)=1。

假设k2 与 k1 - k2不互质,那么 ,k1= k2 + (k1 - k2)。

因为gcd(k2 , k1-k2 )!=1,

所以 ,我们可以得出 ,gcd(k2 + (k1-k2), k2)!=1。

这与条件不符。

所以: gcd(a,b)=gcd(a-b)。

而gcd(a%b)等价于gcd(a- k * b),

因此gcd(a,b)==gcd(b,a%b)成立

扩展欧几里得

首先,解释一下bezout算法:(也称裴蜀定理)

一定存在x,y,使ax+by=gcd(a,b);

证明如下:

我们可以设 ax + by 的最小正整数为s,d=gcd(a,b)。

因为 d| a&& d|b ,所以 d| ax+by。所以 d | s。所以 d<=s。

*** 设q = a/s ,r = a%s = a-q * s = a - q * (ax + by) = a * (1- qx) -b * qy ***

由此可以看出,r 也是关于 a和 b的线性方程的一个值。又因 r>=0&&r<s,且s为 ax+by的最小解,所以r=0。

所以,s|a,同理,我们也可以得出 s|b。

所以,s是a,b的一个公因数。所以s<=d。

因为s<=d&&d<=s,所以s=d。所以 ax+ by的最小正整数解一定为gcd(a,b)。一定可以找到一组整数解,使得ax+by=gcd(a,b)。

最重要的是如何来求x与y。

我们可以设一对 xx与yy,使 b * xx + (a%b) * yy==gcd(b,a%b)

又因上述可知,gcd(a,b)=gcd(b,a%b),

所以 b * xx+(a%b) * yy==gcd(a,b)

根据取模的定义可知:

(a%b)=a-a/b * b

所以:

b * xx+(a-a/b * b) * yy ==gcd(a,b),

那么:a * yy+b * (xx-a/b * yy)==gcd(a,b)

那么将其转化为 ax+by=gcd(a,b)的形式,x=yy,y=xx-(a/b)*yy,得出这个式子,我们就可以在求gcd的基础上求出一组x,y的特解x0,y0(因为满足这种形式的有无数组),具体代码如下:

ll exgcd(ll a,ll b,ll &x,ll &y)
{
	if(b==0) { x=1,y=0;return a;}
	ll d=exgcd(b,a%b,x,y);
	int z=x;
	x=y,y=z-y*(a/b);
	return d;
}

既然我们会求ax+by=gcd(a,b)了,那试想,若题目给出ax+by=c的形式,让我们求解满足的x,y的正整数解(若无,输出-1),这时我们该怎么办呢。。。

若 gcd(a,b) | c, ,设d=c/gcd(a,b),那么得到一组ax+by=gcd(a,b)的解,再使这组解乘上d,不就是满足ax+by的一组解了吗(多理解一下会更好)。

若 gcd(a,b) | c不成立呢,那么我们就找不到一组 正整数解,使原方程成立,因为ax+by的结果一定是gcd(a,b)乘上一个整数 ,所以若gcd(a,b) | c不成立,就得不到一组满足题目条件的整数解。

(qwq…,打的很心累啊,给个五星好评吧 球球了~~~)

在做题时,我们经常会遇到让你求x的最小非负整数解的类似题目,那么,如何求解最小非负整数解呢???

我们知道,满足ax+by=c的x,y有多组正整数解,那么,x 与 y 可不可以用集合来表示呢?

我们若用辗转相除法,只能得到一组特解,但这并不一定是最小的整数解。

那么,我们可以想象,若在ax+by=c中,使x加上一个数t,y减去一个数q,且仍使原式成立,

,那么t与q是什么呢?

设xo与yo属于ax+by=gcd(a,b)的解的集合,

我们设d=c/gcd(a,b)。

所以ax+by=c中: x=d * xo , y=d * yo

那么,若x加上k * b/d, y减上k * a/d ,这样的话,对于原式的成立无影响,我们也可以通过这个式子,求出所有的符合原式的解。

那么:ax+by=c中,x与y的通解也就有了: **x=d * xo + k * b/d ***,y=d * yo - k * b/d

若要求最小正整数解

给出一行代码:

x=【(c*xo/d)%(b/d)+(b/d)】%【b/d】

可能理解有些困难。

为了防止我们求得的x的最小非负整数解是负数,此处加上一个(b/d)再mod一下(b/d),以保证结果为非负数。

推荐一道题:青蛙的约会(模板题)

上代码!!!

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll q11,q22,x,y,m,n,b,a,d;
ll exgcd(ll a,ll b,ll &x,ll &y)//辗转相除求x与y的一组特解
{
	if(b==0) { x=1,y=0;return a;}
	int qwq=exgcd(b,a%b,x,y);
	int z=x;
	x=y,y=z-a/b*y;
	return qwq;
}
int main()
{
	scanf("%lld%lld%lld%lld%lld",&q11,&q22,&m,&n,&b);
	a=n-m;
	d=q11-q22;
	ll ms=exgcd(a,b,x,y);
	if(d%ms)//判断ax+by是否能等于q11-q22
	{
		printf("Impossible");
		return 0;
	}
	ll kk=b/ms;
	printf("%lld",(d*x/ms%kk+kk)%kk);//x与y的最小非负整数解
	return 0;
}

欧拉函数

在这里插入图片描述

其中p1, p2……pn为x的所有质因数,x是不为0的整数。

数论,对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目(因此φ(1)=1)。

证明:

对x而言,小于它且与它互质的数a,质因子分解后的式子里一定不包含x的质因子。

那么,对于φ(x)这个集合而言,它是从1到n,去除掉所有k * p1,k * p2,k * p3…

假设p有两个质因子:

对于与p1互质的,有 x-x/p1 个;对于与p2互质的,有 x-x/p2个,但又因为二者有重合,所以还要加上

x/(p1 * p2),这就简化为了:x*(1 - 1/p1) * (1- 1/p2)。

上述思想为容斥原理。

同理,对于任意一个数p,它的欧拉函数值都满足以上式子。

性质:
  1. 对于一个数n,小于它且与它互质的数的和为: n/2 * φ(n)。

    证:因为gcd(n,x)=gcd(n,n-x),所以与n互质的数关于 n/2 成对存在,所以小于n且与n互质的数的平均值为n/2,所以对于一个数n,小于它且与它互质的数的和为: n/2 * φ(n)。

  2. 若a与b互质,则 φ(ab)= φ(a) * φ(b)。这由欧拉函数的定义式就可以得到。

  3. 设p为质数,若p|n且 pow(p,2)|n,则 φ§=φ(n/p)*p。

    ​ 证: 若 pow(p,2)|n,那么n/p仍然含n所拥有的全部质数,φ(n/p)=n/p * ( 1 - 1/p1) * (1- 1/p2 )…

    ​ φ(n)=n * (1- 1/p1) * (1 - 1/p2)…= φ(n/p)*p。

  4. 设p为质数,若p|n成立 但pow(p,2)|n不成立,那么φ(n)=φ(n/p)*(p-1)。

    证:因为pow(p,2)|n不成立,所以n/p不包含p这个质因数。

    φ(n/p)=n/p * (1- 1/p1) * (1- 1/p2)… , φ(n)=n * (1- 1/p1) * (1 - 1/p2)…*(1 - 1 / p)=φ(n/p) * p * (1- 1/p)= φ(n/p) * (p-1)。

同余

CRT(中国剩余定理)

据说,这是唯一一个以中国来命名的定理。又叫孙子定理。

用现代数学的语言来说明的话,中国剩余定理给出了以下的一元线性同余方程组:(S中m i与m j互质)

求一个满足集合S的通解X;

想必电脑前的你满脸都是疑惑(也可能只是我太蒟蒻。。。)

对于S1(即S集合中的第一项式子),x=a1+k1*m1;

对于 S 2 S2 S2, x = a 2 + k 2 ∗ m 2 x=a_2+k_2*m_2 x=a2+k2m2;

S 3 S3 S3, x = a 3 + k 3 ∗ m 3 x=a_3+k_3*m_3 x=a3+k3m3;…

对于 X X X,要使 X%m1=a1,X%m2=a2,X%m3=a3,所以,X的表达式里,a1到an一定都会出现,且满足条件。

那么,我们如何构造这样一个数X呢?

千万不要忘记题目条件,mi与mj互质。(!!!)

根据上述式子,我们可以让

X − a 1 = k 1 ∗ m 1 , X-a_1=k_1*m_1, Xa1=k1m1,

X − a 2 = k 2 ∗ m 2 , X-a_2=k_2*m_2, Xa2=k2m2,

X − a 3 = k 3 ∗ m 3 . . . . . . X-a_3=k_3*m_3...... Xa3=k3m3......

为了满足 X%m1=a1,我们可以使 a 2 a_2 a2 a n a_n an都乘上 m 1 m_1 m1;

对于X%m2=a2,我们可以使除 a 2 a_2 a2外的 a a a都乘 m 2 m_2 m2

这样,利用归纳法,可以求出X的一个特值:

使M为所有m相乘的结果, M 1 = M / m 1 , M 2 2 = M / m 2 . . . . . . M_1=M/m_1,M2_2=M/m_2...... M1=M/m1,M22=M/m2......以此类推

再求出每个Mi模mi意义下的逆元ti(专业术语不会打,且将就看看吧),

就得到一个X的解: X = M 1 ∗ t 1 ∗ a 1 + M 2 ∗ t 2 ∗ a 2 + . . . . . . M n ∗ t n ∗ a n ; X=M_1 * t_1 *a_1+M_2 * t_2 * a_2 + ...... M_n * t_n * a_n; X=M1t1a1+M2t2a2+......Mntnan;

试着把这个解代入方程集,是不是会奇妙地发现,它对了。

注释,求逆元的意义,请体会:当 X m o d m 1 X mod m_1 Xmodm1时,因为 M 2   M n M_2~M_n M2 Mn都乘过 m 1 m_1 m1,所以都会被消掉,又因 M 1 M_1 M1 * t 1 t_1 t1 % m 1 m_1 m1=1,所以 X%m1=a1%m1,以此类推

推荐一道题:曹冲养猪(模板题)

代码!!!

:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,yu[11],m[11],N=1,M[11],x,y,t[11],qwq,ans;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
	if(b==0) { x=1,y=0;return a;}
	qwq=exgcd(b,a%b,x,y);
	ll z=x;
	x=y,y=z-a/b*y;
	return qwq;
}
int main()
{
	scanf("%lld",&n);
	for(ll i=1;i<=n;i++) 	     scanf("%lld%lld",&m[i],&yu[i]),N*=m[i];
	for(ll i=1;i<=n;i++) M[i]=N/m[i];
	for(int i=1;i<=n;i++)
	{
		exgcd(M[i],m[i],x,y);
		t[i]=x;
		t[i]=(t[i]%m[i]+m[i])%m[i];//求逆元
		ans+=yu[i]*t[i]*M[i];
	}
	printf("%lld",(ans%N+N)%N);
	return 0;
}

扩展CRT(扩展中国剩余定理)

在这里插入图片描述

请看,这张图片,是不是很熟悉呢。

毫无疑问,它与扩展CRT的图片一模一样(因为我用的两张图片一样/233)。

但是,它们的不同之处就在于,扩展CRT中的m没有互质这个限制。

请大家思考一下,在普通CRT中我们会求出一组M和每个M在mod m情况下的逆元t,逆元存在的前提是M与m互质,若m之间不互质,那么M就不与m互质,也就是说,我们无法找到M在mod m下的逆元,这样也就满足不了题目要求,所以,为了解决这个问题,便有了扩展CRT。

首先,我们来考虑两个式子时,能得到的x:

x≡r1(mod m1),x≡r2(mod m2)

我们可以利用二元一次方程的想法:

设未知数k1与k2,使:k1 * m1 +r1= k2 * m2 +r2。

将未知数移到左边,得:k1 * m1-k2 * m2=r2 - r1。

看到这个式子,你有没有想到什么呢???

这样,扩展欧几里得(bezout定理)就派上用场啦!!!

ax + by = c, a变为m1 , b变为m2 , x 变为 k1, y 变为 k2。

m1 * x(k1) + m2 * y(k2) = c(r2 -r1)。

那么,我们就可以求出一组 k1 与 k2 的特值。

那我们的x不就求出来了吗:x=r1 + k1 * m1.(把求得的k1代入x的表达式中)

同时,我们还要再求一下x的最小非负整数解,这在之前已经讲过了。

紧接着,再考虑x的通解 :x = xo + k * lcm(m1 , m2)。(k为任意实数,xo是满足x这个集合的任意解,xo+k * lcm(m1,m2),是因为我们需要加上的这个数,既需要被m1整除,也需要被m2整除)。

再继续想一下,这个式子,我们可不可以,将它变为 x=r(mod m)这样的类型呢?

如果可以,那我们就相当于将 两个式子合并,这样就为 继续求解下面的满足x的式子提供了条件:

x≡xo( mod lcm(m1,m2) )。

这样,是不是有思路了呢!!

总结一下,我们在写扩展CRT这类题目的时候,要将两个式子一个一个进行合并,最后得到满足所有x的解。

推荐题目:Strange Way to Express Integers

上代码:

#include<bits/stdc++.h>
using namespace std;
#define re register
typedef long long ll;
const int N=1e5+10;
int n;
ll k1,k2,r[N],m[N],M,R;
ll mrgcd(ll a,ll b) //扩展欧几里得求k1,k2.
{ 
//	if(a<b) swap(a,b);
	if(b==0) 
	{
		k1=1,k2=0;
		return a;
	}
	ll gcd=mrgcd(b,a%b);
	ll z=k1;
	k1=k2,k2=z-a/b*k2;
	return gcd;
} 
ll kuai(ll a,ll b,ll p)
{
	ll ans = 0;
	while(b>0){
		if(b&1)
			ans = (ans + a) % p;
		a = (a << 1) % p;
		b >>= 1;
	}
	return ans;
}
void work() 
{ 
	R=r[1],M=m[1];//R,M分别记录的是合并后得到的r,m,即:x≡R(mod M)
	for(re int i=2;i<=n;i++) 
	{ 
		ll c=((r[i]-R)%m[i]+m[i])%m[i];//此处理是为了使c为正数,避免c因为是负数而造成对结果的影响。,本质为将ax+by=c化为 ax≡c(mod b)。
		ll gc=mrgcd(M,m[i]);
		if(c%gc) 
		{ 
			R=-1;
			printf("-1");
			break ;
		} 
		ll q1=c/gc,q2=m[i]/gc;
		k1=(kuai(k1,q1,q2)+q2)%q2;//求k1的最小非负整数解
		R=R+k1*M;
		M=M/gc*m[i];//对M值进行更新
		R=((R%M)+M) % M;//对R值进行更新
	} 
} 
int main() 
{ 
	freopen("strange.in","r",stdin);
	freopen("strange.out","w",stdout);
	scanf("%d",&n);
	for(re int i=1;i<=n;i++) 
	scanf("%lld%lld",&m[i],&r[i]);
	work(); 
	if(R!=-1) 
	printf("%lld",R);
	return 0;
} 

费马小定理

对于一个质数p,任意的整数a(a不是p的倍数),都有:

a^(p-1)≡1(mod p)

证明此定理,我们首先需要证明一下欧拉定理。

欧拉定理:

在这里插入图片描述

对于互质的两个数a和n,有:

我们设n的简化剩余系( 本 质是比 n 小且与 n 互质的数)为:b1,b2,b3…bφ(n)。

这里,我们会用到反证法:假设i ! = j,a * b[i] ≡ a * b[j] (mod n) , 因为a与n互质,所以:b[i]≡b[j] (mod n)。但是,我们知道,b[i]显然不与b[j]在模n的情况下同余。所以,

a * b[i] ≡ a * b[j] (mod n)显然不成立。

所以,当一个与n互质的数与b[1]~b[φ(n)]依次相乘,每次得到的数再%n后,得到的数都不一样,

且得到的数都属于b[1]~b[n]区间,这便是乘法封闭。

所以,便得出以下式子:

  • a φ ( n ) a^{φ(n)} aφ(n) * ( b1 * b2 * b3 ……bφ(n)) ≡ b1 * b2 * b3 ……bφ(n)(mod n)

所以: a φ ( n ) a^{φ(n)} aφ(n) ≡ 1 (mod n)。

当n为质数时,φ(n)=n-1,这便与费马小定理不期而遇了: a p − 1 a^{p-1} ap1 ≡1(mod p)

此处,我们将会涉及到逆元的定义: 比如,对于a与p两个数,有一个数x,使得a * x ≡ 1 (mod p),那么,我们就称x为mod p意义下a的逆元

又因为a与p互质,所以: x ≡ 1 a \frac{1}{a} a1 (mod p)。

由费马小定理可得,$ a^{p-2} ≡ ≡ \frac{1}{a}$ (mod p)。那么,我们就可以求得a在mod p意义下的逆元了。

费马小定理的用处,就是用在有关组合数学的题目上,因为有关组合的题目,输出值一般都会比较大,这时,题目就会给你一个较大的质数 ,然后让你输出答案mod上这个质数。我们也都知道,组合数学,一般都要用上除法,我们再将除法转化为同余,就能很轻松地解决相应的问题了。

此处,奉上我码的一个相应的板子(很青涩,但比较简洁)。

求逆元:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=20001000;
ll n,p;
ll f[N],ni[N],ci[N];//jie存阶层,ni存逆元,ci存P-2次方; 
ll fang(ll a,ll b)
{
	ll sum=1;
	while(b)
	{
		a%=p;
		sum%=p;
		if(b&1) sum=(sum%p*(a%p))%p;
		b=b>>1;
		a=(a%p*(a%p))%p;
	}
	return sum%p;
}
int main()
{
	scanf("%d%d",&n,&p);
	f[0]=1;
	f[1]=1;
	for(ll i=2;i<=n;i++) 
	f[i]=(f[i-1]*i)%p;
	ci[n]=fang(f[n],p-2);
	for(ll i=n-1;i>=1;i--)
	ci[i]=(ci[i+1]*(i+1))%p;
	for(ll i=1;i<=n;i++)
	{
		ni[i]=(ci[i]*f[i-1])%p;
	}
	for(ll i=1;i<=n;i++)
	printf("%lld\n",ni[i]);
	return 0;
}

大坑:组合数学!!!

其实本来是不需要写组合的,支撑我写组合的动力,就是因为它又多又复杂了,把它整理一下。其实,这里只是列举一下组合公式的基本应用。

formula

formula

这是组合数学最基本的公式。

第一个式子为排列数:从n个不同元素中依次取出m个元素排成一列,产生的不同排列的数量。

证:m个数中的第一个数有n个可以放,第二个数有n-1个可以放,第三个数有n-2个可以放…第m个数有n-m+1个数可以放。这样便得到上述式子了。

第二个式子为组合数:从n个不同元素中取出m个组成一个集合(不考虑顺序),产生的不同集合的数量。

证:我们先考虑m个数的排列数。试想一下,对于每一个包含m个不同元素的集合,它的排列数为m!,那么我们将排列数再除以m!,便得到m个不同元素的集合有多少种了。

性质:
  1. C n m C^m_n Cnm = C n n − m C^{n-m}_n Cnnm

    证:将二者代入通式计算一下便可得到。

  2. C n m C^m_n Cnm = C n − 1 m C^m_{n-1} Cn1m + C n − 1 m − 1 C^{m-1}_{n-1} Cn1m1

    证:我们可以利用分类的思想来证明。假设当前的数为a,那么,从n个数中取m个,a可以取,也可以不取,分为两类:

    从a除外的n-1个数中取m个 。

    从a除外的n-1个数中取m-1个 。

    当然,也可以用公式来证。怎样舒服取决于你自己。

  3. C n 0 C^0_n Cn0+ C n 1 C^1_n Cn1+ C n 2 C^2_n Cn2+…+ C n n − 1 C^{n-1}_n Cnn1+ C n n C^n_n Cnn= 2 n 2^n 2n

    证:想象一下,我们目前有n位的二进制数, C n 0 C^0_n Cn0代表此二进制数所有的数所有位都是0, C n 1 C^1_n Cn1代表此二进制数中有1位为1, C n 2 C^2_n Cn2代表此二进制数中有2位为1…这样,此二进制数中的1存在的所有情况便枚举全了,最后的值就是 2 n 2^n 2n

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值