2018.7.12(初等数论+组合数学)

初等数论

素数

大家都会,略过
就是 On O ( n ) 的线性筛

素数定理

唯一分解定理

略过

威尔逊定理

p p 为素数,则(p1)!p1(mod p) p ) 同时,它的逆定理也成立。

费马小定理

p p 为素数,a为正整数, a a p互质,则 ap11 a p − 1 ≡ 1 ( mod m o d p p ) 。

欧拉小定理

aφ(m)1(mod m) m ) ,( a a m互质)

欧几里得算法

gcd(a,b)=gcd(b,a g c d ( a , b ) = g c d ( b , a mod m o d b) b )

扩展欧几里得算法

求解形如ax+by=gcd(a,b)方程的一组解。
当b=0时,原方程的解就是x=1,y=0。
假设 bx+(a b x ′ + ( a mod m o d b)y=gcd(a,b) b ) y ′ = g c d ( a , b ) 有解。
bx+(aabb)y=gcd(a,b) b x ′ + ( a − ⌊ a b ⌋ b ) y ′ = g c d ( a , b )
ay+b(xaby)=gcd(a,b) a y ′ + b ( x ′ − ⌊ a b ⌋ y ′ ) = g c d ( a , b )
所以我们也找到了原方程的一组解,按照欧几里得算法那样递归求解即可

裴蜀定理

a,b a , b 是整数,且 gcd(a,b)=d g c d ( a , b ) = d ,那么对于任意的整数 x,y x , y , ax+by a x + b y 都一定是d的倍数,特别地,一定存在整数 x,y x , y ,使 ax+by=d a x + b y = d 成立。
推广:n个整数, a1,a2,a3......an a 1 , a 2 , a 3 . . . . . . a n 为n个整数, d d 是它们的最大公约数,那么存在整数x1......xn使得 x1a1+x2a2+...xnan=d x 1 ∗ a 1 + x 2 ∗ a 2 + . . . x n ∗ a n = d

逆元

O(n) O ( n ) 递推
O(logn) O ( l o g n ) 求单个数的逆元

中国剩余定理

很显然略过

Baby Step Giant Step(BSGS)

用于求解方程 AxmodP=B A x m o d P = B (P为质数)
m=p m = ⌊ p ⌋
x=im+j x = i ∗ m + j
原式转化为 Aim+jB A i m + j ≡ B mod m o d p p
AimBA1j
左边枚举 i i 丢进hash
右边枚举 j j 去与hash表对应

扩展BSGS

显而易见的,BSGS需要求逆元,也就是要求 gcd(A,P)=1 g c d ( A , P ) = 1
也就是说, gcd(A,P)1 g c d ( A , P ) ≠ 1 时,不能用BSGS。
对于方程 ABmodP=C A B m o d P = C ,假设 d=gcd(A,P) d = g c d ( A , P ) ,若 d|C d | C 不成立(特殊条件 B=1 B = 1 暂不考虑),方程无解。
改写原方程
Ad×AB1Cd( A d × A B − 1 ≡ C d ( mod m o d Pd) P d )
后面任然用BSGS

大数分解

大数分解:将n分解为质因数的积的形式(n可能很大,O(√n)算法无法完成)
大数分解给人的第一感觉:玄学
PollardRho P o l l a r d R h o 算法:
1.找到一个数p,使得 p|n p | n ,将 n n 分解为p n/p n / p
2.如果 p p n/p不是素数,继续递归;
3.如果是素数,记录并退出。

大数分解有两个关键:
第一个是如何判定一个数是不是素数。
这里我们用到了 MillerRabin M i l l e r R a b i n 算法:
设我们要判定的数是 p p ,如果存在一个底数a,使得 ap11( a p − 1 ≡ 1 ( mod m o d p) p ) 不成立,那么 p p 肯定不是质数。
随机几次,出错率就比较低了。
为了使出错率更低,还有二次探测的方法。
如果p是奇素数,则 x21( x 2 ≡ 1 ( mod m o d p) p ) 的解为 x=1 x = 1 x=p1( x = p − 1 ( mod m o d p) p )
对于奇素数 r×2s+1 r × 2 s + 1 r r 为奇数),一般对ar ar2 a r ∗ 2 ,…, a(r2s1) a ( r ∗ 2 s − 1 ) 进行二次探测。

另一个是如何找 p p 使得p|n
1.找到一个数 p1 p 1
2.通过某种玄学手段得到与 p1 p 1 对应的一个数 p2 p 2
3.判断 |p2p1| | p 2 − p 1 | 是否能整除 n n ,即gcd(|p2p1|,n)是否大于1;
4.如果大于 1 1 gcd(|p2p1|,n)即为所求,否则 p2 p 2 作为一个新的 p1 p 1 ,继续重复上述过程。
实际使用中,一般用如下公式进行推导: p2=(p21+c)mod p 2 = ( p 1 2 + c ) m o d n n ,其中c为随机常数。这个公式能保证在形成环之前,p2p1基本不会相等。
如何判断是否形成环:标记i位于1,标记j位于2,标记i随着过程不断++,碰到标记j后,标记j的位置*2,并记录当前标记i处的值,这样能保证当j-i>环的大小时,一定能找到环。碰到环了就直接退出,换一个随机常数再找。

一些例题

压惊水题

给定一个长度为n的数组,求ai|aj这样的数对(i,j)有多少个?
n,ai<=106 n , a i <= 10 6
其实只要枚举每一个数组中的数及其他们的倍数就行了
O(nlogn) O ( n l o g n )

BZOJ1477 青蛙的约会

exgcd裸题
x+ansmy+ansn(mod x + a n s ∗ m ≡ y + a n s ∗ n ( m o d L) L )
xyans(nm)(mod x − y ≡ a n s ∗ ( n − m ) ( m o d L) L )
剩下扩欧好了

#include<bits/stdc++.h>
using namespace std;
long long x,b,a,y,m,n,l,t,d,ans;
int ex_gcd(long long &x,long long &y,long long a,long long b)
{
    if(!b) return x=d/a,y=0;
    ex_gcd(x,y,b,a%b),t=x;
    return x=y,y=t-a/b*y;
}
int main() 
{
    scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&l);
    d=(y-x+l)%l;
    a=(m-n+l)%l;
    b=l;
    long long a1=a,b1=b;
     while(b1)
     {
       t=b1;
       b1=a1%b1;
       a1=t;    
     }
    if(d%a1==0)
     {
      ex_gcd(ans,y,a,b);
      while(ans<0) ans=(ans+l)%l;
      printf("%lld",ans%l);
     }
    else 
     printf("Impossible");
    return 0;
}
BZOJ2257 瓶子和饮料

给定n个瓶子的容量,选出其中k个,最大化k个瓶子之间无度量所能表达的最小体积。
kn1000109 k ≤ n ≤ 1000 , 容 量 ≤ 10 9
实际上是答案就是 k k 个瓶子体积的gcd
枚举所有的质因子判断一下是否出现次数超过 k k 即可
O(nmax(V))
https://blog.csdn.net/a1035719430/article/details/81055790

BZOJ2818 GCD

当然是莫比乌斯反演啦
好啦,N这么小怎么可能毒瘤莫比乌斯呢
莫比乌斯可以优化我们这题的做法做到更优
其实我们只要枚举 gcd=p g c d = p ,然后 (x,y) ( x , y ) 可以等价到 (xgcd(x,y),ygcd(x,y)) ( x g c d ( x , y ) , y g c d ( x , y ) )
也就是我们只要在 [1,Np] [ 1 , N p ] 之间直接统计答案即可

BZOJ4173数学

这题还真是鬼畜….
我们也可以鬼畜,打表出答案 φ(n)φ(m)nm φ ( n ) ∗ φ ( m ) ∗ n ∗ m
我们考虑证明
第二个 Σ Σ 中的(n mod m o d k+m k + m mod m o d kk k ≥ k )等价于
n+mknkmk=1 ⌊ n + m k ⌋ − ⌊ n k ⌋ − ⌊ m k ⌋ = 1
将原式转化
这里写图片描述
那么原式答案就为 φ(n)φ(m)nm φ ( n ) ∗ φ ( m ) ∗ n ∗ m

其实打表是很好的,只要打表后面那个 Σ Σ 就可以愉快AC了

bzoj3122随机数生成器

如果高中数列你学的没问题你可以很轻松的写出通项公式
蓝后你就可以得到形如:d=(bc+t)(x1+bc)1的式子了
BSGS!

组合数学

加法原理&乘法原理

略过

排列组合

公式略过
经典例题
某保密装置须同时使用若干把不同的钥匙才能打开。现有7人,每人持若干钥匙。须4人到场,所备钥匙才能开锁。问①至少有多少把不同的钥匙?②每人至少持几把钥匙?
解析:
①每3人至少缺1把钥匙,且每3人所缺钥匙不同。故至少共有C(7,3)=35把不同的钥匙。
② 任一人对于其他6人中的每3人,都至少有1把钥匙与之相配才能开锁。故每人至少持C(6,3)=20把不同的钥匙。

可重复的排列

如果S是一个多重集,它有K个不同的类型元素,各元素分别为 n1,n2,,nk n 1 , n 2 , … , n k 个,那么,S的全排列个数为 n!n1!n2!nk! n ! n 1 ! ∗ n 2 ! ∗ … ∗ n k !

可重复的组合

设S是一个具有k种类型元素的多重集,每种元素均具有无限的重复数.则S的r-组合数为C(r+k-1,r).
例题简单略过

二项式定理

(x+y)n=nk=0Cnknxnkyk ( x + y ) n = ∑ k = 0 n C n n − k x n − k y k
对照杨辉三角理解
特殊情况:
(1+x)n=nk=0Cnknxk ( 1 + x ) n = ∑ k = 0 n C n n − k x k

组合数性质

Crn=Cnrn C n r = C n n − r
显然

Crn=Crn1+Cr1n1 C n r = C n − 1 r + C n − 1 r − 1
显然

rk=0Ckn+k=Crn+r+1 ∑ k = 0 r C n + k k = C n + r + 1 r
略微证明:
C0n=C0n+1 C n 0 = C n + 1 0
C0n+C1n+1+C2n+2++Crn+r C n 0 + C n + 1 1 + C n + 2 2 + … … … + C n + r r
=C1n+2+C2n+2++Crn+r = C n + 2 1 + C n + 2 2 + … … … … + C n + r r
=C2n+3++Crn+r = C n + 3 2 + … … + C n + r r
=Crn+r+1 = C n + r + 1 r
证毕

Cln×Crl=CrnClrnr C n l × C l r = C n r ∗ C n − r l − r
显然

nk=0Ckn=2n ∑ k = 0 n C n k = 2 n
一句话证明:将 x=1 x = 1 带入二项式定理

nk=0(1)k×Ckn=0 ∑ k = 0 n ( − 1 ) k × C n k = 0
一句话证明:将 x=1 x = − 1 带入二项式定理

Crm+n=rk=0Ckm×Crkn C m + n r = ∑ k = 0 r C m k × C n r − k
显然

Cmm+n=mk=0Ckm×Ckn C m + n m = ∑ k = 0 m C m k × C n k
一句话证明:用 Crn=Cnrn C n r = C n n − r 将每一项的左边(含m的组合数)变换一下即转化为前一个式子

k×Ckn=n×Ck1n1 k × C n k = n × C n − 1 k − 1
左右展开即可

n2k=0C2×kn=n21k=0C2×k+1n=2n1 ∑ k = 0 n 2 C n 2 × k = ∑ k = 0 n 2 − 1 C n 2 × k + 1 = 2 n − 1
简要证明:
首先由前面我们可以知道 nk=0Ckn=2n ∑ k = 0 n C n k = 2 n
nk=0(1)k×Ckn=0 ∑ k = 0 n ( − 1 ) k × C n k = 0
式子2告诉我们前面两项相等,式子1告诉我们两项都是 2n1 2 n − 1

nk=1k×Ckn=n×2n1 ∑ k = 1 n k × C n k = n × 2 n − 1
证明:将k的每一项通过 k×Ckn=n×Ck1n1 k × C n k = n × C n − 1 k − 1 换一下
变换得 n×nk=1Ck1n1 n × ∑ k = 1 n C n − 1 k − 1
nk=0Ckn=2n ∑ k = 0 n C n k = 2 n
原式 =n×2n1 = n × 2 n − 1

nk=1k2×Ckn=n×(n+1)×2n2 ∑ k = 1 n k 2 × C n k = n × ( n + 1 ) × 2 n − 2
证明:
将⑼ k×Ckn=n×Ck1n1 k × C n k = n × C n − 1 k − 1 左右同乘 k1 ( k − 1 ) 再化简
k(k1)Ckn=n(n1)Ck2n2 k ( k − 1 ) C n k = n ( n − 1 ) C n − 2 k − 2
然后原始就好处理了。
原式 =nk=1(k2k)Ckn+nk=1Ckn = ∑ k = 1 n ( k 2 − k ) C n k + ∑ k = 1 n C n k
=nk=1n(n1)Ck2n2+n×nk=1Ck1n1 = ∑ k = 1 n n ( n − 1 ) C n − 2 k − 2 + n × ∑ k = 1 n C n − 1 k − 1
=n(n1)×2n2+n×2n1 = n ( n − 1 ) × 2 n − 2 + n × 2 n − 1
=n(n+1)×2n2 = n ( n + 1 ) × 2 n − 2

nk=0(Ckn)2=Cn2n ∑ k = 0 n ( C n k ) 2 = C 2 n n
证明:
对于⑻ Cmm+n=mk=0Ckm×Ckn C m + n m = ∑ k = 0 m C m k × C n k
m=n m = n 即可得到原式

(1+x)n1+xn(mod ( 1 + x ) n ≡ 1 + x n ( m o d n) n )
一句话证明:二项式定理拆开,中间的部分都包括因子n

组合数取模

n1000m1000 n ≤ 1000 , m ≤ 1000
直接上杨辉三角
C(n,m)=C(n1,m1)+C(n1,m) C ( n , m ) = C ( n − 1 , m − 1 ) + C ( n − 1 , m )

n105m105 n ≤ 10 5 , m ≤ 10 5 ,p是素数(比n和m大)
预处理阶乘以及阶乘的逆元

n109m109p105 n ≤ 10 9 , m ≤ 10 9 , p ≤ 10 5 且为素数。
Lucas L u c a s 定理
C(n,m)=C(n%p,m%p)*C(n/p,m/p)
Cmn=Cm$$mod$$pn$$mod$$p C n m = C n $ $ m o d $ $ p m $ $ m o d $ $ p
只需要递归处理 Cmpnp C n p m p \一部分即可。
Lucas L u c a s 定理的证明:
Cmn C n m 就是 (1+x)n ( 1 + x ) n xm x m 项的系数
n=ap+b n = a p + b , m=cp+d m = c p + d
(1+x)ap+b=((1+x)p)a(1+x)b=(1+xp)a(1+x)b ( 1 + x ) a p + b = ( ( 1 + x ) p ) a ( 1 + x ) b = ( 1 + x p ) a ( 1 + x ) b
所以 (1+x)ap+bxcp+d ( 1 + x ) a p + b 中 x c p + d 项的系数就是 Cca×Cdn C a c × C n d

n109m109p=p1c1p2c2pkckpici105 n ≤ 10 9 , m ≤ 10 9 , p = p 1 c 1 ∗ p 2 c 2 … p k c k , p i c i ≤ 10 5
对于不同的 pici p i c i ,我们可以用中国剩余定理定理解决
现在主要的问题就是对 pici p i c i 取模。
Cmn C n m 表示为 k×pix k × p i x ,就可以解决问题了。

Catalan数

非线性递推关系
h(n+1)=nk=2h(k)h(nk+2) h ( n + 1 ) = ∑ k = 2 n h ( k ) ∗ h ( n − k + 2 )
(n3)h(n)=(n/2)[h(3)h(n1)+h(4)h(n2)+......h(n2)h(4)+h(n1)h(3)] ( n − 3 ) h ( n ) = ( n / 2 ) ∗ [ h ( 3 ) ∗ h ( n − 1 ) + h ( 4 ) ∗ h ( n − 2 ) + . . . . . . h ( n − 2 ) ∗ h ( 4 ) + h ( n − 1 ) ∗ h ( 3 ) ] .
线性递推关系
h(n+1)=[(4n6)/n]h(n). h ( n + 1 ) = [ ( 4 n − 6 ) / n ] ∗ h ( n ) .
组合式
h(n+1)=C(2n2,n1)/n. h ( n + 1 ) = C ( 2 n − 2 , n − 1 ) / n .

Fibonacci数

性质:
F(1)+F(2)++F(n)=F(n+2)1 F ( 1 ) + F ( 2 ) + ⋯ + F ( n ) = F ( n + 2 ) − 1
F2(1)+F2(2)++F2(n)=F(n)F(n+1) F 2 ( 1 ) + F 2 ( 2 ) + ⋯ + F 2 ( n ) = F ( n ) ∗ F ( n + 1 )
F(1)+2F(2)++nF(n)=nF(n+2)F(n+3)+2 F ( 1 ) + 2 ∗ F ( 2 ) + ⋯ + n ∗ F ( n ) = n ∗ F ( n + 2 ) − F ( n + 3 ) + 2
F(1)+F(3)++F(2n1)=F(2n) F ( 1 ) + F ( 3 ) + ⋯ + F ( 2 n − 1 ) = F ( 2 n )
F(2)+F(4)++F(2n)=F(2n+1)1 F ( 2 ) + F ( 4 ) + ⋯ + F ( 2 n ) = F ( 2 n + 1 ) − 1
均可通过数学归纳法证明

一一对应

将一个复杂问题转化为另一个对应的简单问题,使得两者的所有情况一一对应;或者将一个不熟悉、冗余的问题转化为一个熟悉、清晰的问题。这是我们解题的重要思路和思考方法

prufer编码

假定已知的n个顶点标志为1,2,…,n,假定T是其中的一棵树,叶节点中有标号最小者。设为a1,a1的邻接点为b1,从T中消去点a1和边(a1,b1)。再从余下的树T1中寻找标号最小的叶节点,设为a2,a2的邻接点为b2,从从T1中消去点a2和边(a2,b2)。如此步骤n-2次,直到最后剩下一条边为止。于是一棵树T对应一序列{b1,b2,…,bn-2},这些数是1~n中的数,并且允许重复。

反过来从b1,b2…bn-2可以恢复树T本身

在序列(1)中找出第一个不出现在序列(2)中的数,这个数显然便是a1,同时形成边(a1,b1),并从(1)中消去a1,从(2)中消去b1。在余下的(1)和(2)中继续以上的步骤n-2次,直到序列(2)为空集为止。这时序列(1)中剩下的两个数x,y,边(x,y)就是树T的最后一条边

Prufer编码指的就是序列 b1,b2,...,bn2 b 1 , b 2 , . . . , b n − 2

Prufer编码的一个重要性质:一个节点的度数为d,那么它在Prufer序列中出现的次数为d-1。

容斥原理

[ DeMorgan D e M o r g a n 定理]
这里写图片描述
拓展
这里写图片描述

一般形式
这里写图片描述

应用
证明欧拉函数
这里写图片描述
证明错排问题
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值