学习笔记--简化剩余系与欧拉函数φ( )
什么是简化剩余系?
所有0<n<=m,(n,m)=10<n<=m,(n,m)=1的n构成了模m的简化剩余系,简称缩系
记这样n的个数为ϕ(m)ϕ(m)
相关性质
-
如果(m,m′)=1,a取遍模m缩系,a′取遍m'缩系
那么am′+a′m取遍mm′缩系
- Prove:已知(a,m)=1,(a′,m′)=1,(m,m′)=1
(am′,m)=1,(a′m,m′)=1
(am′+a′m,m)=1,(a′m+am′,m′)=1 //加上另一个数的若干倍仍互质
(am′+a′m,mm′)=1
- 所以如果(n,m)=1,ϕ(nm)=ϕ(n)∗ϕ(m) -
- $\phi(pe)=(p-1)*p=p^e*(1-1/p) $ p是质数
- Prove:[1,pe]中与p不互质的数的个数为pe/p=pe−1
ϕ(pe)=pe−pe−1=pe∗(1−1/p) - 特殊地,若p是一个质数,则ϕ(p)=p−1
- Prove:[1,pe]中与p不互质的数的个数为pe/p=pe−1
- $\phi(pe)=(p-1)*p=p^e*(1-1/p) $ p是质数
什么是欧拉函数
在数论,对正整数n,欧拉函数是小于或等于n的数中与n互质的数的数目。欧拉函数用希腊字母phi()或ϕ() (念fai去声)表示,phi(n)表示正整数n的欧拉函数。
举个栗子:[1,12]中与12互质的有1,5,7,11。
(别忘了,a与b互质表示gcd(a,b)=1,故1也算)
所以ϕ(12)=4。
很显然这个ϕ(m)就是上文简化剩余系中所提到的
欧拉函数的计算
由上文简化剩余系的性质可知
计算公式:ϕ(p)=∏ϕ(pcii)=∏(pci∗(1−1/pi))=n∗∏(1−1/pi)
计算方式
直接按照定义
int euler_phi(int n){
int m=(int)sqrt(n+0.5);
int ans=n;
for(register int i=2;i<=m;i++)
if(n%i==0)
{//最好要先除后乘,防止结果溢出
ans=ans/i*(i-1); //上文推导得
while(n%i==0)n=n/i;//将n中所有因子i筛去
//确保下一个i是n的质因子
}
if(n>1)ans=ans/n*(n-1);//防止n为最后一个质因子
return ans;
}
例题: hdu 1787裸欧拉函数简单变式
有没有O(N)预处理出一张欧拉函数表的方法呢?当然有,在欧拉筛的基础上稍加改动即可,想要看懂代码请您先熟练欧拉筛
这是一个欧拉筛
void Euler_Prime()
{
memset(is_Prime,1,sizeof(is_Prime));
memset(pri,0,sizeof(pri));
is_Prime[0]=0;
is_Prime[1]=0;//特判
for(register int i=2;i<=n;i++) {
if(is_Prime[i])
pri[tot++]=i; //----1
for(register int j=0; j<tot && i*pri[j]<=n;j++){
is_Prime[i*pri[j]]=0;
if(i%pri[j]==0) break; //-----2
//-----3
}
}
}
使用欧拉筛时无非在代码中1,2,3处三种情况:
(话说第二条的证明找了挺久,好多人都直接略过,感觉我真的太菜了
-
判定i是一个质数,根据上文性质ϕ(i)=i−1
-
在2处,ϕ(i∗pri[j])=ϕ(i)∗pri[j]
Prove:设x=pri[j]∗i,易知此时i包含pri[j]这个质因子,即i的质因子与x的相同,根据欧拉函数的直接计算方式,
ϕ(x)=x∗∏(1−1/pi)=pri[j]∗i∗∏(1−1/pi)=pri[j]∗ϕ(i)
-
在3处,易知i与pri[j]互质,根据欧拉函数性质(也是积性函数性质)
ϕ(x)=ϕ(i)∗ϕ(pri[j])=ϕ(i)∗(pri[j]−1)
然后就可以看懂代码了
inline void get_phitable(){
bool is_pri[maxn];
int num[1000005],tot=0,tmp;
memset(is_pri,0,sizeof(is_pri));
is_pri[1]=1;
phi[1]=1;
for(ri i=2;i<=maxn;i++){
//printf("%d\n",i);
if(!is_pri[i]){
num[++tot]=i;
phi[i]=i-1;
}
for(ri j=1;j<=tot;j++){
tmp=num[j]*i;
if(tmp>=maxn)break;
is_pri[tmp]=1;
if(i%num[j]==0){
phi[tmp]=num[j]*phi[i];
break;
}
else {
phi[tmp]=(num[j]-1)*phi[i];
}
}
}
return ;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?