2017国庆郑州集训Day1

基本算法

递推、递归、分治
二分、倍增
贪心

递推

指通过观察、归纳,发现较大规模问题和较小规模问题之间的关系,用一些数学公式表达出来

在一些题解中,和“计数DP”是指同一个概念

看例题

例 1

用 1 * 2 的骨牌,覆盖 2 * n 的棋盘的方案数?

解:很经典的Fibonacci 数
O(n) 求解

例 2

长度为 2n 的合法括号序列个数
合法括号序的定义:
空串合法
若 A 合法,则 ( A ) 合法;
若 A 和 B 合法,则 AB 也合法。

解:比较经典的Catalan 数
O(n ^ 2) 求解
可以优化到 O(n) - O(1)

对于一个左括号 一定有唯一右括号与其匹配

例 3

有 n 个人
你想把他们划分为若干个小组,每个小组至少有一个人,每个人恰好属于一个组
问方案数
定义两种方案是不同的,当且仅当存在一个小组,只在其中一个方案出现

解:Bell 数
B[n+1] = sum { 0<=k<=n } C(n, k) * B[k]

例 4

求排列 P 的数量,满足 P[i] != i

解:错位排列数
容斥或者递推求

递归

所谓递归,是指函数“自己调用自己”的一种编程方法
在解决一个问题时,如果发现问题能拆解为一个或多个相同规模的子问题时,就可以考虑使用这种方法求解

例 - 汉诺塔

有三个柱子
有 n 个圆盘从小到大依次叠在一个柱子上
你希望通过若干步,把它们移动到另一个柱子上
移动规则:
每次可以移动一个圆盘
任意时候,大圆盘不能在小圆盘上方

解:
解决规模为 n 的问题可以分三步:
把 n-1 个圆盘移动到另一个柱子上
把大圆盘移动到第三个柱子上
把 n-1 个圆盘移动到大圆盘上
注意到第 1 和第 3 步是相同形式、规模更小的子问题
于是可以设计递归算法

二分
倍增
贪心
详见专题博客…..

OI中的数学

即数论啊什么的 还有各种定理 反正我是听的糊里糊涂的的的

吕欣大佬给我们讲了:
模算术、Bezout 定理、欧几里德算法
素数和筛法、常见数论定理
积性函数和Dirichlet卷积

模算术

模意义下的加减乘除
逆元的若干种求法
同余关系、剩余类

bezout 定理

我们阐述 Bezout 定理:
方程 ax + by = c 有解,当且仅当 gcd(a, b) | c
定理的证明:必要性显然,充分性见下一页

ps:gcd为求最小公约数

欧几里得算法

gcd(a, b) = gcd(a - b, b)
证明比较简单
事实上,定理直接给出了一种计算 gcd 的方式,直接根据上述公式计算,复杂度 O(\log min(a, b))

扩展欧几里得算法

事实上,我们可以直接在欧几里德算法求解 gcd(a, b) 的过程中,构造一组 ax + by = gcd(a, b) 的解
这个方法依赖于递归的思想
边界:b = 0 时, a * 1 + b * 0 = gcd(a, b)
设我们找到了一组 bx + (a % b)y = gcd(a, b) 的解,那么:
bx + (a - [a / b] * b]) y = gcd(a, b) ==>
ay + b * (x - [a / b] * y) = gcd(a, b)
令 x’ = y, y’ = (x - [a / b] * y),可以得到:
ax’ + by’ = gcd(a, b)

二元一次不定方程的通解

令 d = gcd(a, b)
当我们求出 ax + by = c 的一组解 x0、y0 之后
方程的通解具有以下形式:
x = x0 + k * (b / d)
y = y0 - k * (a / d)
直观理解一下,这是一个设法让正负互相抵消的过程

素数

定义:大于 1 的、只被 1 和它本身整除的正整数称为素数
唯一分解定理,又称算术基本定理:
对于正整数 n,我们一定可以将其写为若干个质数的幂的乘积形式,即
n = ∏ (pi ^ ai),其中 pi 为质数
并且,这种分解是唯一的

素数筛法

在解数论题的过程中,我们常常需要知道小范围内的素数的分布情况(区间内的素数个数、判断某个数是不是素数…)
埃拉托斯特尼筛
欧拉筛
* 杜老师筛(什么破名字QWQ),洲阁筛

埃氏筛

(很有用)
如果我们要筛出 [1, n] 内的所有素数,使用 [1, √n] 内的素数去筛就可以了
设数组 mark[],mark[i] 表示 i 是否被某个素数筛过
从 2 开始枚举每个数 i:
若 mark[i] = 0,表示 i 没有更小的素因子,从而知道 i 是素数。枚举 i 的所有倍数 j,令 mark[j] = 1
若 mark[i] = 1,知道 i 是一个合数
复杂度 O(n\lg\lg n)

埃氏筛的复杂度上界为 O(n lglg n)
这个证明比较复杂,我们这里只证明其复杂度不超过 O(n\log n):
定义调和数 Hn = (1 / 1 + 1 / 2 + … + 1 / n)
我们有 Hn ~ ln n (不严谨地,可以考虑导数帮助理解)
对于 <= √n 的一个素数 p,我们用它去筛合数的计算量为 n / p
于是总计算量为 n * (∑ { 1 / p | p < √n } ) <= n * H_n <= O(n\log n)
PS:Hn ~ ln n 是一个很重要的结论,以后我们还会多次见到它

埃氏筛的应用

在进行筛法的同时,我们可以对 [1, n] 内的合数进行素数分解,从而完成一些其他工作
例如,对于一个素数 i,枚举它的倍数 j 时,把 j 中的所有因子 i 除干净,就知道 j 的质因子分解中 i 的幂了
有一类问题,需要你预处理区间 [L, R] 内的素数分布
其中 R - L <= 10^6, R <= 10^10
此时,区间 [L, R] 的长度比较小;另一方面,√R <= 10^5。我们就可以考虑使用埃氏筛的思想来求解问题
用一个数组 mark2[] 维护区间 [L, R] 被筛的结果,用素数 p 去筛 [L, R] 的计算量为 (R - L) / p,总计算复杂度大概为 H_{R-L},即 O((R - L) \log R)

威尔逊定理

p 是质数的充要条件为
(p - 1)! ≡ -1 (mod p)
充分性:
若 p 不是质数,则 gcd( (p-1)!, p ) > 1,与 Bezout 定理相悖
必要性:
考虑 [1, p) 中的某个数 x 和它的乘法逆元 y
如果 x != y, 那么 xy ≡ 1,可以令它们互相抵消
于是只需要考虑 x 是自己的逆元的情况
解 x^2 ≡ 1 ==> p | (x - 1) * (x + 1)
因为 p 是质数,只有可能是 x ≡ ±1,得证

欧拉函数

欧拉函数 ��(n),表示不大于 n 的、与 n 互质的正整数个数
令 n = ∏ (pi^ai),则 ��(n) = n * ∏ (1 - 1/pi)
计算方法:
对 n 进行质因子分解的过程中维护,O(√n)
埃氏筛的时候顺便维护,复杂度同埃氏筛

关于欧拉函数的两个公式

∑ { ��(d) | d | n } = n
证明:在 [1, n] 中,恰好有 ��(d) 个数和 n 的 gcd 为 n / d
n > 1 时, ∑ { d | gcd(d, n) = 1 } = n * ��(n) / 2
证明:当 gcd(x, n) = 1 时,可得 gcd(n - x, n) = 1,可以将与 n 互质的数两两配对
对于 n <= 2 的情况,特殊讨论

HAOI 2012 外星人

给定 N 的质因数分解,问 N 取过多少次 �� 之后变成 1
N 有至多 50 个质因数,每个质因数 <= 10^5,每个质因数的幂 <= 10^9

解:
所有质因数最后都要变成若干个 2,然后消失
每次只能消去一个 2
除了 N 为奇数的第一次运算,每次运算一定能消去一个 2
只有某一轮里有奇质数,一定能贡献一个 2
于是问题转化为,每个质因子最后会贡献多少个 2
递推即可

剩余系

剩余类:
给定 n,整数按照模 n 取值的不同,可以分为 n 个子集,称为剩余类
剩余系:
给定 n,从模 n 的 n 个剩余类中各取一个数构成的集合,称为模 n 的一个剩余系,剩余系一般指完全剩余系
简化剩余系:
也称既约剩余系,是模 n 的完全剩余系的一个子集,其中每个元素与n 互素
容易验证,简化剩余系中恰好有 ��(n) 个元素

欧拉定理

考虑模 n 的一个简化剩余系 S
因为 S 中的每个元素和 n 互质,它们在模 n 意义下存在乘法逆元
任取一个 a,使得 (a, n) = 1
考虑集合 T = { ax | x ∈ S }
容易验证:
|T| = |S|,且 |T| 中的数模 n 互不同余
|T| 中的数均和 n 互质
由此,可得 T 也是模 n 的一个简化剩余系

因为 S 和 T 均为模 n 的简系,可得:
∏ {x | x ∈ S} ≡ ∏ {y | y ∈ T} ==>
∏ {x | x ∈ S} ≡ ∏ {ax | x ∈ S} ==>
∏ {x | x ∈ S} ≡ a ^ {|S|} * ∏ {x | x ∈ S} ==>
a^{|S|} ≡ 1
这就是欧拉定理:
若 (a, n) = 1,则 a ^ ��(n) ≡ 1

欧拉定理EXT

由欧拉定理可以推导出一些很有用的结论
费马小定理:
若 p 是质数且 (a, p) = 1,则 a ^ (p-1) ≡ 1 (mod p)
一个应用:a ^ (p - 2) ≡ 1 / a (mod p),可以通过快速幂求逆元
欧拉定理 EXT:
若 (a, p) = 1,则 a ^ x ≡ a ^ (x % ��(p)) (mod p)
任何情况下,若 x > ��(p),则 a ^ x ≡ a ^ (x % ��(p) + ��

eg:

BZOJ 3884 上帝与集合的正确用法

T 组询问
每组询问给出 P,求:
2 ^ (2 ^ (2 ^ (…) ) ) (mod P)
T <= 1000
P <= 10^7

解:
由欧拉定理EXT,问题可以转化为求指数部分 mod ��(p)
这实际上是一个相同形式的子问题,递归求解即可
一个有趣的推论:
对于一个数 x,不断执行 x = c^x
在模 P 意义下,O(\log P) 次操作之后,x 变成一个常数
SH/JL/LN/HE/SX/HL OI 2017 相逢是问候

中国剩余定理

可以用来求解这样的同余方程组:
给定长度为 k 的数组 a[] 和数组 m[],求解
x ≡ a[i] (mod m[i])
保证 m[i] 两两互质
解的存在性?唯一性?求法?

推导

定理:令 M = ∏ (m[i]),方程在 [0, M) 中有唯一解 x0,并且通解具有 kM + x0 的形式
这里证明唯一性:
设 x1 != x2 是方程的两个解,我们有
x1 - x2 ≡ 0 (mod m[i])
x1 - x2 是每个 m[i] 的倍数,它们必然也是 M 的倍数,即 M | x1 - x2
于是,x1 和 x2 最多只有一个落在区间 [0, M) 中
解的存在性,我们通过一种构造算法来证明

构造解

令 Mi = M / m[i],因为 (M[i], m[i]) = 1,我们可以找到 Mi 模 m[i] 的乘法逆元 t[i]
考察 Mi * t[i]:
j = i 时,M[i] * t[i] ≡ 1 (mod m[j])
j != i 时,M[i] * t[i] ≡ 0 (mod m[j])
令 x = ∑ (a[i] * M[i] * t[i])
不难验证,x 是满足要求的

模数不互质

模数不互质的时候,怎么办?
将方程两两合并,考虑方程组:
x ≡ a1 (mod m1)
x ≡ a2 (mod m2)
令 x = k1 * m1 + a1 = k2 * m2 + a2
则有 k1 * m1 - k2 * m2 = a2 - a1
由 Bezout 定理判断解的存在性,用 extend_gcd 解方程即可
事实上,可以得到一个推论:
如果存在解,则 x 在 [0, lcm(m1, m2) ) 中有唯一解

应用

可以直接解决一类问题
有些数学计算题,给出的模数 m 并不是一个素数
而很多计算在模素数(或素数的幂)下会方便很多
于是可以将 m 分解质因数,求答案模每个素数(的幂)的值,最后使用中国剩余定理合并

LUcas 定理

C(n, m) ≡ C(n / p, m / p) * C(n % p, m % p) (mod p)
证明:
核心思想:用两种方法展开 (x + 1) ^ n,考虑 x^m 一项的系数
重要公式:(x + 1) ^ p ≡ x^p + 1 (mod p)

eg:

小 Q 的集合

给定 n, m, k,求
∑(i <= n) C(n, i) * ( (i^k - (n-i)^k) ^ 2 ) mod m
n <= 10^1000000
m <= 1000000
k <= 1000000

解:
x ^ k ≡ (x % m) ^ k
Lucas 定理、组合数公式

线性筛

一种优秀的筛法
线性复杂度的来源:每个数只会被它的最小的质因子筛掉
线性筛

简单证明: 设有一个数 m = p * q * s
其中 p 是最小的质因子,q 是另外一个质因子
如果 m 会被 q 筛掉,那一定是在 i = p * s 时筛掉的
但是我们发现 i = p * s 时,j 枚举到 p 这个质数时就会 break
把每个数被筛的过程画成一张图,发现相同的质因子是在连续的几步被筛掉的
实际上,筛的过程相当于按照质因子降序分解了每个数

积性函数

若有函数 f(n) 的定义域为正整数,值域为复数,称为数论函数
进一步地,若数论函数 f(n) 满足:
对于互质的 p、q,有 f(p * q) = f(p) * f(q)
称为积性函数,或者说函数满足积性
更进一步地,若数论函数 f(n) 满足:
对于任意 p、q,有 f(p * q) = f(p) * f(q)
称为完全积性函数

常见的积性函数

除数函数 σk(n)=∑(d|n) d ^ k,表示n的约数的k次幂和
约数个数函数 τ(n)=σ0(n)=∑(d|n) 1,表示n的约数个数,一般也写为d(n)。
约数和函数 σ(n)=σ1(n)=∑(d|n) d,表示n的约数之和
欧拉函数 ��(n)
莫比乌斯函数μ(n):
n 有平方因子时值为 0
否则值为 (-1) ^ (质因子个数)
元函数 e(n) = [n = 1],完全积性
恒等函数 I(n) = 1,完全积性
单位函数 id(n) = n,完全积性

Dirichlet卷积

对两个数论函数进行的运算
设我们有两个数论函数 f(n) 和 g(n)
它们的狄利克雷卷积是一个新的函数 (f * g) (n)
设这个函数为 h
我们有 h(n) = ∑(k|n) f(k) * g(n / k)

性质

积性函数的狄利克雷卷积仍然满足积性
证明:对互质的 p、q,有
h(p) * h(q)
= ∑ { f(a) * g(b) | ab = p }* ∑ { f(c) * g(d) | cd = q }
= ∑(ab = p, cd = q) f(ac) * g(bd)
=∑(xy = pq) f(x) * g(y)
=h(p * q)
注意:完全积性函数的狄利克雷卷积不一定满足完全积性
狄利克雷卷积满足结合律,即对于三个数论函数 f、g、h,有 (f * g) * h = f * (g * h)
证明:
(f * g) * h (n)
= ∑(ab = n) h(b) * (∑(xy = a) f(x) * g(y))
= ∑(xyb = n) f(x) * g(y) * h(b)
= ∑(xy = n) f(x) * (∑(ab = y) g(a) * h(b))
= f * (g * h) (n)
Dirichlet 卷积同时也具有交换律、分配律
Dirichlet 卷积运算存在单位元(元函数 e):f * e = e * f = f

常见的公式

id = �� * 1
d = 1 * 1
σ = id * 1
e = 1 * μ (反演式) *
�� = id * μ *

eg:····HDU 5628
令 g(n) = ∑(i1|n) ∑(i2 | i1) ∑(i3 | i2) …∑(ik | ik - 1) f(ik)
其中已经告诉你 f(i) 在 1 ~ n 的取值,没有特别规律
求 g(1) ~ g(n) ,答案对 1e9 + 7 取模
n、k <= 1e5

解:
g = f * (1 ^ k)
卷积满足结合律,1 ^ k可以用快速幂的思路乘 log n 次算出来
如何求两个函数的狄利克雷卷积?
f(a) * g(b) => h(a * b)
一次卷积德复杂度为 n * log(n)
PS:本题存在一个 log 的组合解法

积性函数 的预处理

借助线性筛,可以在 O(n) 时间内预处理出某种数论函数在 [1, n] 的取值
我们以约数个数函数为例说明
莫比乌斯函数、欧拉函数、约数和函数的预处理都应该熟练掌握

约数个数函数

n = ∏ (pi^ai)
d(n) = ∏ (ai + 1)
我们维护一个辅助数组 num[x] ,表示 x 的最小的质因子的幂次
线性筛每次会筛掉一个数最小的质因子,这让我们可以很方便地维护 num[],从而计算 d[]
约数个数函数

离散对数

求解关于 x 的方程 A ^ x ≡ B (mod P)
P 是质数,P <= 1e9

大步小步算法(bSGS)

我们设置一个步长 m
则任意一个可行解可以写成 x = am + b (0 <= b < m)
A ^ (am + b) = B mod P => A ^ b = B * A ^ (-am) mod P
把 0 <= b < m 的 A ^ b 预先算出来,扔到哈希表中
查询的时候暴力枚举 a,算出等式右边,在哈希表中查询
复杂度 O(P / m) + O(m)
m = √P 时,取得最优复杂度 O(√P)
如果用 map 实现哈希表,还要乘一个 log

扩展大步小步法

如果 P 不是质数,怎么办?
若 (A, P) = 1,算法还是可以跑的,求逆元改成 extend_gcd 就行了
(A, P) != 1时,问题出在哪儿?
A 不存在关于 P 的逆元
令 d = gcd(A, P)
A/d * A ^ (x - 1) = B/d (mod (P/d) )
递归求解
最多 log(P) 层,注意最后算出来的答案 x 要加上层数
因此,需要特判掉 x <= log(P) 的情况

ps:经过的今天的学习,告诉我们oier数学一定要学好
!!!!!!!

To be continued…..

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值