一些数论函数
约数和函数(数论积性)
f(n)=∑d|nd
若
n=pa11pa22pa33...pakk
则
f(n)=(1+p21+p31...+pa11)(1+p22+p32...+pa22)...(1+p2k+p3k...+pakk)
约数个数函数(数论积性)
f(n)=∑d|n1
若
n=pa11pa22pa33...pakk
则
f(n)=(1+a1)(1+a2)...(1+ak)
分解质因数
朴素算法 O(N−−√)
for(LL i = 2; i * i <= n; i++)
while (n % i == 0) n /= i;
Pollard Rho算法 O(n1/4)
LL pollard_rho(LL n, LL c)
{
LL i = 1, k = 2;
LL x = rand() % (n - 1) + 1;
LL y = x;
while(true)
{
i++;
x = (multi(x, x, n) + c) % n;
LL d = gcd((y - x + n) % n, n);
if(1 < d && d < n) return d;
if(y == x) return n;
if(i == k)
{
y = x;
k <<= 1;
}
}
}
组合数取模 (nm)modp
Lucas 定理( p 为质数)
(nm)=(sp+qtp+r)=(st)(qr)modp
O(logpn∗p) 计算组合数取模
p 不为质数
首先我们有
那我们将模数变为
paii
再用中国剩余定理合并就可以了
问题转化为
(nm)=n!m!(n−m)!modpM
令 n!=T∗pk ,其中 p不能整除T ,如果能够成功地将 n! 分解成这个样子,那么
(nm)=n!m!(n−m)!=Tn∗T−1m∗T−1n−m∗pkn−km−kn−mmodpM
而 T与p 互质,能求逆元,问题就可做了。
如何将 n!分解为T∗pk 呢?
首先我们可以将阶乘写成这个样子
n!=1∗2∗...p∗...∗2p∗...∗kp∗....n 然后我们就有
n!=(1∗2∗...∗(p−1)∗(p+1)∗...∗(2p−1)∗(2p+1)∗...∗(kp−1)∗(kp+1)∗...∗n)∗k!∗pk
前面一坨东西算出来, k! 是个子问题,我们在这一层成功提取了 pk ,解决子问题之后累积起来就行了
中国剩余定理( CRT )
x=a1modm1
x=a2modm2
…
x=anmodmn
假设整数
m1,m2,...,mn
互质,则对于任意
a1,a2,...,an
,方程组有解
设M=m1∗m2∗...∗mn,Mi=M/mi
设Ti=M−1imodmi
则
x=a1t1M1+a2t2M2+...antnMn+kM