这是最后一篇即时笔记了呢
数学
数论
数论各种神器算法
线性递推逆元:i−1=(p−⌊p÷i⌋)×(p%i)−1%p。
以及阶乘和阶乘的逆元的递推:n!≡n×(n−1)!(modp),(n!)−1≡n−1×((n−1)!)−1。
可以用这个方法在O(n)预处理后,O(1)计算组合数。
线性筛
这个线性筛不仅可以筛质数,还可以计算积性函数。φ,μ等函数都可以用这种方法计算。详见贾志鹏 线性筛。
可以用矩阵,也可以用等比数列求和。
这里介绍一些等比数列求和的方法。
现在我们要求s=∑i=0nai=1+a+a2+⋯+an(modp)。
如果p是质数,我们就可以利用等比数列的求和公式s=a−1an+1−1≡(an+1−1)×(a−1)−1(modp)。时间复杂度O(logn)。
如果p不是质数,则答案可以如下计算:(an+1−1)%((a−1)p)÷(a−1)。
上述方法可概括如下:若c=ba是整数,那么c%p=(a%(bp))÷b。(注意a不能边算边模,a一定要保持原样,即必须保证参与计算的b∣a。如果要涉及到更复杂的膜 蛤 模合数,请参见Virtual NOIP Day 2 总结。)
证明如下:设c≡x(modp),a≡t(modbp)。
由同余的性质得,c−x=np,a−t=bmp。
将c的定义带入得:ba−x=np,知a−bx=bnp。得a=bnp+bx。
又知a=bmp+t,带入得bnp+bx=bmp+t,即bx−t=bp(m−n),知bx≡t(modbp)。
由a−t=bmp知bc−t=bmp,得t=b(c−mp)。令k=c−mp,则t=bk。
带入得bx≡bk(modbp),约去b得x≡k(modp)。证毕。
当然还可以用分治。现在要求s=∑i=0nai=1+a+a2+⋯+an(modp)。
如果n是偶数,设n=2k,那么s=1+a+⋯+ak+ak+1+⋯+a2k=(1+ak)(1+⋯+ak−1)+a2k
如果n是奇数,设n=2k+1,那么
s=1+a+⋯+ak+ak+1+⋯+a2k+1=(1+ak+1)(1+⋯+ak)
取边界条件k=0,分治即可。
系数这么大,怎么办?写高精
写高精是不可能的,这辈子都不会写高精的!
我们考虑把方程弱化为同余方程,取一个大数~~(比如某个数)~~,最好是long long级别的,读入时直接把系数模p,然后枚举解即可。
取long long级别的Dark♂数,预处理出F1,F2,⋯,F100000模这个数的余数,枚举判断即可。
随机数生成的方法
最简单的方法当然是直接rand()
(是否srand()
都可以)。
下面介绍一种生成(几乎)不可预测的随机数的方法,对于OI赛制来说没有什么用,但是对于Codeforces这种需要防hack的赛制,就很有用了。
1 2 3 4
| void *a=new char; void *b=(void *)(NULL); int x=a-b; delete a;
|
上述代码会生成一个随机数x,请注意x一定是8的倍数。
考场上怎么办?数论打表找规律!千万不要像我一样蠢到手算,面前摆的可是一台高科技计算机呢,怎么能不写程序找规律呢?找找规律就发现是一次函数了w_w。
证明我有时间再补吧。
看一道推广题:半质数的线性组合
结论是2pqr−pq−pr−qr。
欧拉函数($\varphi $函数)
φ(x)=∑i=1x[i⊥x],即[1,x]中与x互质的数的个数。
φ(ab)=φ(a)φ(b) (a⊥b)
中国生育剩余定理
long long O(1) 快速乘
有时候我们要计算a×b%p,其中a,b,p都是long long级别的数字,那么我们怎么办呢?
有一个玄学类型,叫做long double,它作为浮点数类型,可以保存相当大的数,误差相对不是很大。
再回顾一下模的概念:x%p=a−⌊px⌋×p。
于是我们的思路就是,用long double暂时算出积的值并除以p,加上一点微小的EPS,转换为long long后乘以p,再用long long下积的值减去上面计算的结果,加上p后再模p即可。
上面说起来比较抽象,让我们看看代码。
1 2 3 4 5 6 7 8 9 10 11
| ll mul(ll a,ll b,ll p){ ll res; a%=p; b%=p; res=(ll)((long double)(a)*b/p+EPS); res=res*p; res=a*b-res; res+=p; res%=p; return res; }
|
压行后的代码如下:
1 2 3 4
| ll mul(ll a,ll b,ll p){ a%=p,b%=p; return (a*b-(ll)((long double)(a)*b/p+EPS)*p+p)%p; }
|
注意这个方法在数字较大的时候很可能不准确,如果要保险,请使用龟速乘(O(logn))。
1 2 3 4 5 6 7 8 9 10
| ll mul(ll a,ll b,ll p){ ll ans=0; while (b){ if (b&1) ans=(ans+a)%p; a=(a<<1)%p; b>>=1; } return ans; }
|
组合数学
Catalan数
可以用生成函数解(学长的方法),也可以用图形直接转化为组合数(米尔嘉的神奇方法)。
Cn=(n+1)!n!(2n)!可以表示:
- 有n个结点的不同形态的二叉树的个数
- 含n对括号的合法括号序列的个数
- 长度为n的入栈序列对应的合法出栈序列个数
- 通过连接顶点而将n+2边的凸多边形分成三角形的方法个数
根据Catalan数公式的推导过程,可以用Cn=Cn2n−Cn+12n进行无除法的递推。
将问题分解为,按键n次输入一个长度为m的序列和长度为m的序列有多少个是合法括号序列。前者可以通过dp计算,而后者就是Catalan数,最后将这两个相乘再累加即得答案。
注意到每个元素的选取是独立的。
考虑某一个元素的选取,将选取方案转化为三角形上的折线,因此答案为2nk。
应用:愚蠢的组合数
概率论
最优策略一定是选当前剩下的最贵的壶。将壶的价格从小到大排序为a1,a2,⋯,a2n。那么第i个壶被选中的概率是pi=2n−1i−1,于是总期望E=∑i=12npiai。
NOIP 2018初赛T8
结论:在[0,1]内找n个数,其中最大数的期望是n+1n,最小数的期望是n+11。
期望
独立事件:若P(AB)=P(A)P(B),则A和B是独立的。
期望的性质:线性性:Ex(aX+bY)=aEx(X)+bEx(Y)
独立随机变量的期望:若X,Y独立,则Ex(XY)=Ex(X)Ex(Y)
条件概率。