初等数论
素数
大家都会,略过
就是
O(n)
O
(
n
)
的线性筛
素数定理
唯一分解定理
略过
威尔逊定理
p p 为素数,则 p) p ) 同时,它的逆定理也成立。
费马小定理
p p 为素数,为正整数, a a 与互质,则 ap−1≡1 a p − 1 ≡ 1 ( mod m o d p p ) 。
欧拉小定理
mod m) m ) ,( a a 与互质)
欧几里得算法
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′+(a−⌊ab⌋b)y′=gcd(a,b)
b
x
′
+
(
a
−
⌊
a
b
⌋
b
)
y
′
=
g
c
d
(
a
,
b
)
ay′+b(x′−⌊ab⌋y′)=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∗a1+x2∗a2+...xn∗an=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=i∗m+j
x
=
i
∗
m
+
j
原式转化为
Aim+j≡B
A
i
m
+
j
≡
B
(
mod
m
o
d
p
p
)
即
左边枚举
i
i
丢进表
右边枚举
j
j
去与表对应
扩展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×AB−1≡Cd(
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
分解为与
n/p
n
/
p
;
2.如果
p
p
或不是素数,继续递归;
3.如果是素数,记录并退出。
大数分解有两个关键:
第一个是如何判定一个数是不是素数。
这里我们用到了
MillerRabin
M
i
l
l
e
r
R
a
b
i
n
算法:
设我们要判定的数是
p
p
,如果存在一个底数,使得
ap−1≡1(
a
p
−
1
≡
1
(
mod
m
o
d
p)
p
)
不成立,那么
p
p
肯定不是质数。
随机几次,出错率就比较低了。
为了使出错率更低,还有二次探测的方法。
如果是奇素数,则
x2≡1(
x
2
≡
1
(
mod
m
o
d
p)
p
)
的解为
x=1
x
=
1
或
x=p−1(
x
=
p
−
1
(
mod
m
o
d
p)
p
)
。
对于奇素数
r×2s+1
r
×
2
s
+
1
(
r
r
为奇数),一般对,
ar∗2
a
r
∗
2
,…,
a(r∗2s−1)
a
(
r
∗
2
s
−
1
)
进行二次探测。
另一个是如何找
p
p
使得:
1.找到一个数
p1
p
1
;
2.通过某种玄学手段得到与
p1
p
1
对应的一个数
p2
p
2
;
3.判断
|p2−p1|
|
p
2
−
p
1
|
是否能整除
n
n
,即是否大于1;
4.如果大于
1
1
,即为所求,否则
p2
p
2
作为一个新的
p1
p
1
,继续重复上述过程。
实际使用中,一般用如下公式进行推导:
p2=(p21+c)mod
p
2
=
(
p
1
2
+
c
)
m
o
d
n
n
,其中c为随机常数。这个公式能保证在形成环之前,基本不会相等。
如何判断是否形成环:标记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+ans∗m≡y+ans∗n(mod
x
+
a
n
s
∗
m
≡
y
+
a
n
s
∗
n
(
m
o
d
L)
L
)
x−y≡ans∗(n−m)(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个瓶子之间无度量所能表达的最小体积。
k≤n≤1000,容量≤109
k
≤
n
≤
1000
,
容
量
≤
10
9
实际上是答案就是
k
k
个瓶子体积的
枚举所有的质因子判断一下是否出现次数超过
k
k
即可
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)∗n∗m
φ
(
n
)
∗
φ
(
m
)
∗
n
∗
m
我们考虑证明
第二个
Σ
Σ
中的(
mod
m
o
d
k+m
k
+
m
mod
m
o
d
k≥k
k
≥
k
)等价于
⌊n+mk⌋−⌊nk⌋−⌊mk⌋=1
⌊
n
+
m
k
⌋
−
⌊
n
k
⌋
−
⌊
m
k
⌋
=
1
将原式转化
那么原式答案就为
φ(n)∗φ(m)∗n∗m
φ
(
n
)
∗
φ
(
m
)
∗
n
∗
m
其实打表是很好的,只要打表后面那个 Σ Σ 就可以愉快AC了
bzoj3122随机数生成器
如果高中数列你学的没问题你可以很轻松的写出通项公式
蓝后你就可以得到形如:的式子了
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=0Cn−knxn−kyk
(
x
+
y
)
n
=
∑
k
=
0
n
C
n
n
−
k
x
n
−
k
y
k
对照杨辉三角理解
特殊情况:
(1+x)n=∑nk=0Cn−knxk
(
1
+
x
)
n
=
∑
k
=
0
n
C
n
n
−
k
x
k
组合数性质
⑴
Crn=Cn−rn
C
n
r
=
C
n
n
−
r
显然
⑵
Crn=Crn−1+Cr−1n−1
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=Crn∗Cl−rn−r
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×Cr−kn
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=Cn−rn
C
n
r
=
C
n
n
−
r
将每一项的左边(含m的组合数)变换一下即转化为前一个式子
⑼
k×Ckn=n×Ck−1n−1
k
×
C
n
k
=
n
×
C
n
−
1
k
−
1
左右展开即可
⑽
∑n2k=0C2×kn=∑n2−1k=0C2×k+1n=2n−1
∑
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告诉我们两项都是
2n−1
2
n
−
1
⑾
∑nk=1k×Ckn=n×2n−1
∑
k
=
1
n
k
×
C
n
k
=
n
×
2
n
−
1
证明:将k的每一项通过
k×Ckn=n×Ck−1n−1
k
×
C
n
k
=
n
×
C
n
−
1
k
−
1
换一下
变换得
n×∑nk=1Ck−1n−1
n
×
∑
k
=
1
n
C
n
−
1
k
−
1
由
∑nk=0Ckn=2n
∑
k
=
0
n
C
n
k
=
2
n
得
原式
=n×2n−1
=
n
×
2
n
−
1
⑿
∑nk=1k2×Ckn=n×(n+1)×2n−2
∑
k
=
1
n
k
2
×
C
n
k
=
n
×
(
n
+
1
)
×
2
n
−
2
证明:
将⑼
k×Ckn=n×Ck−1n−1
k
×
C
n
k
=
n
×
C
n
−
1
k
−
1
左右同乘
(k−1)
(
k
−
1
)
再化简
得
k(k−1)Ckn=n(n−1)Ck−2n−2
k
(
k
−
1
)
C
n
k
=
n
(
n
−
1
)
C
n
−
2
k
−
2
然后原始就好处理了。
原式
=∑nk=1(k2−k)Ckn+∑nk=1Ckn
=
∑
k
=
1
n
(
k
2
−
k
)
C
n
k
+
∑
k
=
1
n
C
n
k
=∑nk=1n(n−1)Ck−2n−2+n×∑nk=1Ck−1n−1
=
∑
k
=
1
n
n
(
n
−
1
)
C
n
−
2
k
−
2
+
n
×
∑
k
=
1
n
C
n
−
1
k
−
1
=n(n−1)×2n−2+n×2n−1
=
n
(
n
−
1
)
×
2
n
−
2
+
n
×
2
n
−
1
=n(n+1)×2n−2
=
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)n≡1+xn(mod
(
1
+
x
)
n
≡
1
+
x
n
(
m
o
d
n)
n
)
一句话证明:二项式定理拆开,中间的部分都包括因子n
组合数取模
n≤1000,m≤1000
n
≤
1000
,
m
≤
1000
直接上杨辉三角
C(n,m)=C(n−1,m−1)+C(n−1,m)
C
(
n
,
m
)
=
C
(
n
−
1
,
m
−
1
)
+
C
(
n
−
1
,
m
)
n≤105,m≤105
n
≤
10
5
,
m
≤
10
5
,p是素数(比n和m大)
预处理阶乘以及阶乘的逆元
n≤109,m≤109,p≤105
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+b中xcp+d
(
1
+
x
)
a
p
+
b
中
x
c
p
+
d
项的系数就是
Cca×Cdn
C
a
c
×
C
n
d
n≤109,m≤109,p=p1c1∗p2c2…pkck,pici≤105
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(n−k+2)
h
(
n
+
1
)
=
∑
k
=
2
n
h
(
k
)
∗
h
(
n
−
k
+
2
)
(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)]
(
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)=[(4n−6)/n]∗h(n).
h
(
n
+
1
)
=
[
(
4
n
−
6
)
/
n
]
∗
h
(
n
)
.
组合式
h(n+1)=C(2n−2,n−1)/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)+2∗F(2)+⋯+n∗F(n)=n∗F(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(2n−1)=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,...,bn−2 b 1 , b 2 , . . . , b n − 2
Prufer编码的一个重要性质:一个节点的度数为d,那么它在Prufer序列中出现的次数为d-1。
容斥原理
[
DeMorgan
D
e
M
o
r
g
a
n
定理]
拓展
一般形式
应用
证明欧拉函数
证明错排问题