数论复习 | 提高组数论算法汇总
欧拉函数计算
(phi(n)=n*(1-frac 1 {p_1})*(1-frac 1 {p_2})*...*(1-frac 1 {p_n}))
线性筛原理
(n = p * m)表示形式唯一
for(int i=2~n){
if(!flg[i]){
p[++tot]=i;
f[i] = ...
}
for(p[j] in p){
flg[p[j]*i]=1;
if(i%p[j]) break;
}
}
质数:(phi(p)=p-1)
(phi(p^k)=p^k-p^{k-1})
1...n中与n互质的数的和:(S(n)=frac {phi(n)*n} 2)
欧拉定理
(a^{phi(m)}equiv 1 pmod m),a和m互质,用简化剩余系证明
扩展欧拉定理
想象一个矩阵,长为(phi(m)),从第二列开始每一列都同余
逆元
((b,c) ot = 1)则不存在逆元
如果((b,c) = 1)则可以用欧拉定理,(bcdot b^{phi(c)-1}equiv 1 pmod c)
所以(b^{-1}=b^{phi(c)-1} pmod c)
特殊地,如果c为质数,(b^{-1}=b^{phi(c)-1}=b^{c-1-1}=b^{c-2} pmod c)
求(1-n)的逆元:一个一个求是nlogn
线性求(m是质数):(inv[i]=(m-left lfloor frac m i ight floor)*inv[m~ ext{mod}~i])
也可以大常数求阶乘及其逆元,但是在求组合数的时候极其好用
第一种方法的证明:
设$m=k*i+t $
(k*i+t equiv 0 pmod m)
扩展欧几里得
(ax+by= (a,b))
边界:
递归:
所以
可以得到
这样的到了一组解
可以用来求解逆元:(bxequiv 1 pmod m)
相当于解(b*x+(-m)*k=1)
相当于(b*x+m*k=1)
原根
阶
最小正整数(n)使得(a^n equiv 1pmod m)
原根
((g,m)=1)
(g^{phi(m)}equiv 1 pmod m),且(phi(m))是(g)膜(m)的阶,(g)为原根
形式:(2,4,p^x,2*p^{x})
求法:
求m的原根时,因为原根一般都比较小,那么就从(2)开始枚举(g),只需要判断(g)模(m)的阶是否是(φ(m))就好了,怎么判呢,枚举每个数(i(1leq i < φ(m)))算(g^iequiv 1pmod m),若满足则这个(g)一定不是原根
(g^0,g^1,...g^{p-1})互不相同,表示了1~p-1所有数
所以$x*y pmod m equiv g^p *g^q pmod m equiv g^{p+q} pmod m $
可以资瓷把乘法转化成加法
原根个数:$ phi(phi(m)) $
例题:ZROI851
二次剩余
存在(x)使得(x^2 equiv m pmod p)
勒让德符号:
(left(frac n p ight)=1),是二次剩余
(=-1) ,不是
(=0) ,n是p倍数
有二次剩余的条件:(n^{frac {p-1} 2 } equiv 1pmod p)
求法:1~p-1中有一半的数有二次剩余,另一半没有,随机a,期望两次找到
https://www.cnblogs.com/cjyyb/p/10830057.html
https://blog.csdn.net/qq_35950004/article/details/99676601
斐波那契数列
可以矩阵求
小常数:5有二次剩余时可以带进(sqrt 5)求出
更快的做法:多组测试数据的时候考虑底数不变,以(16)为底,预处理出通项公式中(x^0...x^{65535},y^0...y^{65535})
莫比乌斯反演
刚刚复习过,基础内容查看之前博客,本质是另一种容斥
式子:
或者
性质:
与欧拉函数关系:
BSGS
求(a^b equiv c pmod p)
要求:((a,c)=1)
思想是预处理出一部分数
令(p=sqrt c),处理出(a^0,a^1,...,a^{p-1}),存到(hashtable)或者(map)里
然后把(x)表示成(x=i*p-j)的形式
那么
考虑枚举后面的(i),查表前面的是否存在,即可计算出(j)
多次询问可以考虑变大块的大小,后面询问的时间会变小
当块取(B=T*frac N B,B=sqrt{N*T})时最优
代码实现:注意枚举顺序
for(int i=0;i<m;i++){
M[s]=i;//能更新就更新
s=1ll*s*x%p;
}
int t=ksm(x,m);s=1;
for(int i=1;i<=m;i++){
s=1ll*s*t%p;
if(M.count(s)){printf("%d
",i*m-M[s]);return 0;}
}
puts("no solution");return 0;
卢卡斯定理
注意,如果下面比上面小,整个式子都为0
可以递归求解,也可以直接看作在(p)进制下,直接循环
推论:如果在(p)进制下n有一位小于m的一位,那么(C(m,n))被(p)整除
证明显然,带入公式即可
EX lucas
参见我的博客
中国剩余定理
这里说的是EXCRT,至于CRT,那并不重要
求解同余方程组
(m)不一定两两互质,令(M=prod _{ileq k} m_i)
设前(k)个方程组成的同于方程组的一个解为(x),那么(x+i*M)都是满足条件的解
我们要求的是(x+t*M equiv a_k pmod {m_k})
(t*M+j*m_k = a_k -x),这样就可以用(exgcd)求出解
如果无解,则方程组误解
否则(x=x+t*M),递归