数轮部分
数论
这一部分只考虑整数
一些定义
完全积性函数
为完全积性函数,则
积性函数
为积性函数,则在时,有
常见的积性函数
,为的唯一分解中互不相同的质数
莫比乌斯函数,时,,当的唯一分解的质数的次数都为1,为的质数种类次方,否则
表示的约数个数
表示的约数和
表示n的约数的次方的和(除数函数)
筛法
埃拉托斯特尼筛法
埃拉托斯特尼筛法筛素数
主体思想是逐个去掉所有质数的倍数,枚举到的下一个就是质数
int vis[N],pri[N],cnt;void Eratosthenes(int n){ vis[0]=vis[1]=0;cnt=0; for(int i=2;i<=n;i++)vis[i]=1; for (int i=2;i<=n;i++){ if (vis[i]){ pri[cnt++]=i; if (1ll*i*i>n)continue; for (int j=i*i;j<=n;j+=i){ vis[j]=0; } } }}线性筛(欧拉筛)
线性筛的主体思想是让每个数都被自己最小的质因数筛掉
void Euler(int n){ cnt=0; for (int i=2;i<=n;i++)vis[i]=0; for (int i=2;i<=n;i++){ if (!vis[i])pri[cnt++]=i; for (int j=1;j<=cnt;j++){ if (1ll*i*pri[j]>n)break; vis[i*pri[j]]=1; if (i%pri[j]==0)break; } }}注意代码中说明已经到了的最小质数,如果继续,那么接下来的数就不是被最小的质数筛掉了,以为的最小质数是
用线性筛求一些函数
求,设为的最小质因子,且
如果,
如果,
int phi[N];void get_phi(int n){ cnt=0;phi[1]=1; for (int i=2;i<=n;i++)vis[i]=0; for (int i=2;i<=n;i++){ if (!vis[i])pri[++cnt]=i,phi[i]=i-1; for (int j=1;j<=cnt;j++){ if (1ll*i*pri[j]>n)break; if (i%pri[j]==0){ vis[i*pri[j]]=1;phi[i*pri[j]]=pri[j]*phi[i]; break; } vis[i*pri[j]]=1;phi[i*pri[j]]=(pri[j]-1)*phi[i]; } }}求,设为的最小质因子,
如果,
如果,
int mu[N];void get_mu(int n){ cnt=0;mu[1]=1; for (int i=2;i<=n;i++)vis[i]=0; for (int i=2;i<=n;i++){ if (!vis[i])pri[++cnt]=i,mu[i]=-1; for (int j=1;j<=cnt;j++){ if (1ll*i*pri[j]>n)break; if (i%pri[j]==0){ vis[i*pri[j]]=1;mu[i*pri[j]]=0; break; } vis[i*pri[j]]=1;mu[i*pri[j]]=-mu[i]; } }}求,设,,,为的最小质因子
如果,
如果,,
我们需要维护,即最小质因子的个数,令为的最小质因子的个数,则有
如果,,
如果,,
int d[N],num[N];void get_d(int n){ cnt=0;d[1]=1; for (int i=2;i<=n;i++)vis[i]=0; for (int i=2;i<=n;i++){ if (!vis[i])pri[++cnt]=i,d[i]=2,num[i]=1; for (int j=1;j<=cnt;j++){ if (1ll*i*pri[j]>n)break; if (i%pri[j]==0){ vis[i*pri[j]]=1;num[i*pri[j]]=num[i]+1;d[i*pri[j]]=d[i]*(num[i*pri[j]]+1)/num[i*pri[j]]; break; } vis[i*pri[j]]=1;num[i*pri[j]]=1;d[i*pri[j]]=2*d[i]; } }}求,,,为的最小质因子
令
如果,,,
如果,,
int dsum[N],gsum[N];void get_dsum(int n){ cnt=0;dsum[1]=1; for (int i=2;i<=n;i++)vis[i]=0; for (int i=2;i<=n;i++){ if (!vis[i])pri[++cnt]=i,dsum[i]=1+i,gsum[i]=1+i; for (int j=1;j<=cnt;j++){ if (1ll*i*pri[j]>n)break; if (i%pri[j]==0){ vis[i*pri[j]]=1; gsum[i*pri[j]]=pri[j]*gsum[i]+1; dsum[i*pri[j]]=dsum[i]*(gsum[i*pri[j]])/gsum[i]; break; } vis[i*pri[j]]=1; gsum[i*pri[j]]=1+pri[j]; dsum[i*pri[j]]=(1+pri[j])*dsum[i]; } }}狄利克雷卷积
数论分块
用于计算形如的式子
若能预处理的前缀和,则可在的时间计算上式
一维
先看简单情况考虑计算,即为
我们按照的值分块,设这块区间为
则有 ,取倒数有,
则
右端点为
向上取整
计算
注意到
多维
计算
只需要对一个取交集即可,
任意指数
计算
同上可知
复杂度为
莫比乌斯反演
普通形式
首先有恒等式
设,,则
即
简单应用
主要形式,可直接带入验证
上述形式等价与
故
对有,,即,则,
对,有,则
对互异素因子数目函数,即,则,
拓展形式
,即,为的逆
前缀和
如果将每一个素数都看作一个维度,这就是一种高维前缀和.从小到大遍历所有素数 𝑝,并将 𝑛处的函数值累加到 𝑛𝑝处.这和筛法 的遍历顺序是一致的.因此,这一算法可以在 时间内计算出长度为 的数列的 前缀和.类似地,利用逐维差分就可以在相同时间复杂度内求出数列的 差分.
int f[N],g[N];void di_presum(int n){ for (int i=0;i<=n;i++)vis[i]=0,f[i]=g[i]; for (int i=2;i<=n;i++){ if (vis[i])continue; for (int j=1,ij=i;i*j<=n;j++,ij+=j){ vis[ij]=1; f[ij]+=g[j]; } }}void di_diff(int n){ for (int i=0;i<=n;i++)vis[i]=0,g[i]=f[i]; for (int i=2;i<=n;i++){ if (vis[i])continue; for (int j=n/i,ij=i*j;j>=1;j--,ij-=j){ vis[ij]=1; g[ij]-=f[j]; } }}杜教筛
用低于线性的时间求
构造一个,满足的前缀和可以很快的求出
,最后一步可以这么理解括号内的乘积都是小于等于的
则
时间复杂度
Min_25筛
低于线性时间求积性函数前缀和
要求:是关于的可以快速求值的完全积性函数之和;可以快速求值
为第小的质数,
为的最小质因数,
发现答案即为
考虑计算
直接递推
从大到小枚举,当时转移增加值不为零,可后缀和优化
考虑计算,发现只有这几个点有用
一般,我们计算
表示埃筛第轮筛后剩下的的和
有递推公式
的结果是最小质因子大于的数的次方和
然后就可以用合并得到了
类欧几里得算法
计算
如果,,
计算
如果
如果,,
最大公因数
欧几里得算法
扩展欧几里得算法
,又,带入得
有,
最终会有,,
int exgcd(int a,int b,int& x,int& y){ if (!b)return x=1,y=0,a; int d=exgcd(b,a%b,x,y); int t=x; x=y; y=t-(a/b)*y; return d;}欧拉函数
一些性质
积性函数
欧拉反演
欧拉定理
,则
费马小定理
扩展欧拉定理
裴蜀定理
存在使得
二元一次不定方程
硬币问题
有的面值的硬币若干种,且,那么最大的不能被表示的面值为多少
时,答案为
树与序列
逆元
线性求逆元
中国剩余定理
基本形式
求
计算
为的逆元
3.
int a[N],r[N];int crt(int k){ int n=1,ans=0; for (int i=1;i<=k;i++)n*=r[i]; for (int i=1;i<=k;i++){ int m=n/r[i]; ans=(ans+a[i]*m*pow(m,r[i])%n)%n; } return (ans%n+n)%n;}且
构造,设
带入有
,
以此类推
for (int i = 0; i < k; ++i) { x[i] = a[i]; for (int j = 0; j < i; ++j) { x[i] = r[j][i] * (x[i] - x[j]); x[i] = x[i] % p[i]; if (x[i] < 0) x[i] += p[i]; }}(粘的代码)
扩展
,,不一定互质
当时,无解
否则可以求出一组,使得
多个方程两两合并
升幂引理
,表示的标准分解中的次数,即
第一部分
对所有素数和满足的整数,
若,则:
若,则对奇数有:
:
则有
则有
第二部分
对所有奇素数,
若,则:
若,则对奇数有:
我们只需要证明的情况
时,我们只要证
设,(下面有点啰嗦)
则有
下面用数学归纳法证明第一个式子
设,
以此类推得
与上面相似,我们只要证明的情况
时,我们只要证
设,与上面完全相同
则有
下面用数学归纳法证明第二个式子
设,
以此类推得
第三部分
若且
对奇数,
对偶数,
对上述,
若,则:
时,会把第二部分推导部分倒数第三行分母中的约掉,不能用上面的方法
易知奇数的偶数次方模余,则
则
阶乘取模
定理
对自然数,当且仅当时素数时,
定理
对自然数,有
取,当且仅当模的原根存在
推论
对素数和正整数,有
阶乘余数
计算
,当时取,其余情况取
,,当时取,其余情况取
公式
,为进制下的各个位数之和
定理
定理
对素数,有
对比系数有,
算法
素数幂模情况
一般模数情况
用中国剩余定理直接计算即可
同余方程
定义
对整数和一元整系数多项式,其中未知数,称形如的方程为关于未知数的模的一元同余方程,若,则上式称为次同余方程
素数幂模同余方程
我们有,则
引理
,,且
若,则存在整数使得,是方程的解
若且,则都可
若且,则不能由上式构造
假设是解,带入后有
则
三种情况对应即可
注意到我们推理中只有最后一步用到,那么我们可以对着最后的式子构造解
推论
,则存在
无公共解,则原方程的解数与相同
素数模同余方程
,其余的同上
定理
若有个不同的解,则
,
推论
定理
至多有个根
推论
若的解数大于,则
定理
若的解数不为,则必定存在的整系数多项式与同解集
不妨设
运用费马小定理即可
定理
设,则方程有个解当且仅当存在整系数多项式
必要性:
则与同解,则知
充分性:
设的解数为
则
定理
设则方程有解当且仅当,若有解,解数为
必要性:
方程有解,则
充分性:
,
由定理3知有个解
高次同余方程(组)的求解
我们可以进行下面转化
同余方程组-同余方程
模合数-模素数幂-模素数(引理)
我们最后只需考虑
将代换为可消去项
只需考虑
线性同余方程
二次剩余
可化为次剩余
二次剩余
定义
,若存在整数使得,则称为模的二次剩余,否则称为模的二次非剩余
判别法
对奇素数,和满足的,有
由费马小定理,
则
则若,则
又知
可证上述结论
对于奇素数,模意义下的二次剩余和二次非剩余都有个
符号
对奇素数和整数,定义符号如下:
对任意整数,
则
(完全积性)对任意整数
则对整数
二次互反律
设是两个不同的奇素数,则
模意义下的开平方
时,为一个解
算法
求解
找到一个使得为模非二次剩余(需要特判),期望两步找到,定义
解为,(疑似需要复数类)
阶&原根
阶
对于且,满足同余式的最小正整数称为模的阶,记作或
幂的循环结构
对于且,幂次模两两不同余
对于且,同余式成立当且仅当
对于且,有
对于且,有
对于且,使得
原根
对于如果存在且使得,则称为模的原根
原根判定定理
对整数和,为模的原根,当且仅当对于的每个素因子有
原根个数
模的原根个数为
原根存在定理
模的原根存在,当且仅当,其中为奇素数且
求原根的算法
从小到大逐一枚举可能的数即可
函数
对于,定义为能使对所有都成立的最小正整数
由幂的循环结构性质5知:
递推公式
引理
引理
对于且,有且对于有
引理
对于,为奇素数且,
定理
数
对于合数,对所有满足的整数有,则为 数
判别法
合数为 数当且仅当无平方因子且对于的任意质因子均有
数为奇数,没有平方因子,且至少有个不同的素因子
离散对数
定义
取有原根的正整数,和其一原根,对满足,存在唯一整数,使得
我们称这个为以为底,模的离散对数,记作,
性质
设是模的原根,
也是模的原根,
大步小步算法
在的时间内求解
,其中,则,也就是
然后预处理所有,在枚举即可
可用存储,会多一个
扩展算法
求解
就是想办法把底数和模数变得互质
无解,否则得到
无解,否则得到
转化成普通的问题
高次剩余&单位根
高次剩余
整数,整数和正整数互素,若存在整数使得,则称为模的次剩余,为模的次方根;否则称为模的次非剩余
定理
设整数,整数和正整数互素,设模的原根存在,且是模的一个原根,记
为模的次剩余,当且仅当
当为模的次剩余时,在同余意义下,模恰好有个互不相同的次方根,且它们具有形式
模的次剩余类的个数为,且它们全体就是
则,又为模的原根,所以和与的某次幂同余,设,原方程等价于,等价于,该方程有解当且仅当且通解的形式为
对于,又由阶的性质知,又方程有解当且仅当即,也即由阶的性质其等价于
定理
设整数,奇数和正整数
当时
恒为模的次剩余
模的次方根有且仅有一个
模的次剩余类个数为,且它们就是全体既约剩余类
当时,
为模的次剩余当且仅当
当为模的次剩余时,同余意义下,模恰好有个互不相同的次方根,且他们具有相同的形式
模的次剩余类的个数为,且他们的全体就是
则,因为为奇数,设,则原方程等价于
当时总是有解
当时,第一个方程有解当且仅当,即,第二个条件有解当且仅当同上知等价于,根据两个方程,知解的形式为
单位根
定义
对于模数 𝑚,元素 的 𝑘次方根称为模 𝑚的 𝑘次单位根.特别地,如果 𝑥是模 𝑚的一个 𝑘 次单位根,且它不是模 𝑚 的任何 𝑘′ <𝑘 次单位根,那么,也称 𝑥为 模 𝑚 的 𝑘 次本原单位根 原根是模的次本原单位根
性质
模数,为它的函数
所有与互素的整数都是模的次本原单位根
元素是模的次单位根,且为的任意倍数,那么也是模的次单位根
元素是模的次(本原)单位根,那么元素是模的次(本原)单位根
当遍历的因数,所有模的次本原单位根恰好构成模的次单位根的一个划分。对于给出次单位根之间的双射,且保持上述划分不变
模的次本原单位根存在,当且仅当,,特别的,模的次本原单位根存在,称为模的原根
元素是模的次单位根,当且仅当,且对任意素因子
只证明
由函数性质知,模的次本原单位根总是存在,设为,且,对于,设,总有,因此是次本原单位根,又所有的阶都是的因子,故由性质
定理
设是模的一个次方根,当遍历模的全体次单位根时,遍历模的全体次方根
定理
对于模数,设模的原根存在,且是模的次本原单位根,那么是次单位根,当且仅当它可以表示为的幂次
模意义下的开方
改良算法
求解为素数幂
特别的对于的情形,还要保证,将换成
设,当是模的次剩余时,总是模的次单位根,对任意为单位根之间的双射,取
原方程两边同时取次幂
左边是因为,则
考虑,从开始以次开即可
即求解
设,设,由于是次单位根,那么是次单位根,设是模的次本原单位根,那么是次本原单位根,存在可知
为计算上式,需要找到摸 的一个次非剩余,则有,分别为,次本原单位根
计算,取,考虑进制当前为计算完时
可用计算
一般情形
若
若则,该方程有解当且仅当,最终解为