数论复习 | 提高组数论算法汇总
数论复习 | 提高组数论算法汇总
欧拉函数计算
\(\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)\not = 1\)则不存在逆元
如果\((b,c) = 1\)则可以用欧拉定理,\(b\cdot 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 \right \rfloor)*inv[m~\text{mod}~i]\)
也可以大常数求阶乘及其逆元,但是在求组合数的时候极其好用
第一种方法的证明:
设$m=k*i+t $
\(k*i+t \equiv 0 \pmod m\)
扩展欧几里得
\(ax+by= (a,b)\)
边界:
递归:
所以
可以得到
这样的到了一组解
可以用来求解逆元:\(bx\equiv 1 \pmod m\)
相当于解\(b*x+(-m)*k=1\)
相当于\(b*x+m*k=1\)
原根
阶
最小正整数\(n\)使得\(a^n \equiv 1\pmod 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(1\leq i < φ(m))\)算\(g^i\equiv 1\pmod 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\right)=1\),是二次剩余
\(=-1\) ,不是
\(=0\) ,n是p倍数
有二次剩余的条件:\(n^{\frac {p-1} 2 } \equiv 1\pmod 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\n",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 _{i\leq 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\),递归