数论!!!(是我配不上的·东西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=1∏m(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=1∏m( ∑ j = 0 c [ i ] \sum\limits^{c[i]}_{j=0} j=0∑c[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,它的欧拉函数值都满足以上式子。
性质:
-
对于一个数n,小于它且与它互质的数的和为: n/2 * φ(n)。
证:因为gcd(n,x)=gcd(n,n-x),所以与n互质的数关于 n/2 成对存在,所以小于n且与n互质的数的平均值为n/2,所以对于一个数n,小于它且与它互质的数的和为: n/2 * φ(n)。
-
若a与b互质,则 φ(ab)= φ(a) * φ(b)。这由欧拉函数的定义式就可以得到。
-
设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。
-
设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+k2∗m2;
S 3 S3 S3, x = a 3 + k 3 ∗ m 3 x=a_3+k_3*m_3 x=a3+k3∗m3;…
对于 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, X−a1=k1∗m1,
X − a 2 = k 2 ∗ m 2 , X-a_2=k_2*m_2, X−a2=k2∗m2,
X − a 3 = k 3 ∗ m 3 . . . . . . X-a_3=k_3*m_3...... X−a3=k3∗m3......
为了满足 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=M1∗t1∗a1+M2∗t2∗a2+......Mn∗tn∗an;
试着把这个解代入方程集,是不是会奇妙地发现,它对了。
注释,求逆元的意义,请体会:当 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} ap−1 ≡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;
}
大坑:组合数学!!!
其实本来是不需要写组合的,支撑我写组合的动力,就是因为它又多又复杂了,把它整理一下。其实,这里只是列举一下组合公式的基本应用。
这是组合数学最基本的公式。
第一个式子为排列数:从n个不同元素中依次取出m个元素排成一列,产生的不同排列的数量。
证:m个数中的第一个数有n个可以放,第二个数有n-1个可以放,第三个数有n-2个可以放…第m个数有n-m+1个数可以放。这样便得到上述式子了。
第二个式子为组合数:从n个不同元素中取出m个组成一个集合(不考虑顺序),产生的不同集合的数量。
证:我们先考虑m个数的排列数。试想一下,对于每一个包含m个不同元素的集合,它的排列数为m!,那么我们将排列数再除以m!,便得到m个不同元素的集合有多少种了。
性质:
-
C n m C^m_n Cnm = C n n − m C^{n-m}_n Cnn−m
证:将二者代入通式计算一下便可得到。
-
C n m C^m_n Cnm = C n − 1 m C^m_{n-1} Cn−1m + C n − 1 m − 1 C^{m-1}_{n-1} Cn−1m−1
证:我们可以利用分类的思想来证明。假设当前的数为a,那么,从n个数中取m个,a可以取,也可以不取,分为两类:
从a除外的n-1个数中取m个 。
从a除外的n-1个数中取m-1个 。
当然,也可以用公式来证。怎样舒服取决于你自己。
-
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 Cnn−1+ 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 。