欧拉函数:指从1-n中与n互质的数的个数
首先要知道,一个数 $n$ 分解质因数之后会变成这样一个形式:
$n$ = $p1k1$ + $p2k2$+ ... + $pnkn$
而欧拉函数: $φ$= $n$ * (1-1/p1) * (1-1/p2) * ... * (1-1/pn).
证明:
1. 由于n可以被分解为p1,p2..的倍数,那么首先要用 n-n/p1-n/p2-...
2. 加上pi*pj的倍数,因为这当中有被重复减去的数,要加回去
3. 加上pi*pj*pk的倍数,因为有可能三个数的倍数被减去
4.....依次类推
朴素做法:
//欧拉函数:1-n当中与n互质的数的个数 #include <bits/stdc++.h> //#define int long long using namespace std; const int N=1e5+10,mod=1e9+7; string s; int n,t,a[N],f[N],res,num,ans; bool vis[N]; int main() { std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>t; while(t--){ cin>>n; res=n; for(int i=2;i<=n/i;i++){ if(n%i==0){ //res=res*(1-1/i); res=res/i*(i-1);//和上面的公式一样的,只是相除有可能因为浮点数影响判断 while(n%i==0) n/=i; } } if(n>1) res=res/n*(n-1); cout<<res<<endl; } return 0; }
欧拉筛法求欧拉函数:
#include <bits/stdc++.h> //#define int long long using namespace std; const int N=1e5+10,mod=1e9+7; string s; long long n,t,a[N],f[N],res,num,ans,prime[N]; bool vis[N]; long long get_ouler(int u) { res=0,f[1]=1; for(int i=2;i<=u;i++){ if(!vis[i]){ prime[++num]=i; f[i]=i-1;//如果是质数,那么它与他互质的个数就是i-1 } for(int j=1;prime[j]<=n/i;j++){ vis[prime[j]*i]=true; if(!(i%prime[j])){ f[prime[j]*i]=f[i]*prime[j]; break; } f[prime[j]*i]=f[i]*(prime[j]-1); } } for(int i=1;i<=n;i++) res+=f[i]; return res; } int main() { std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>n; cout<<get_ouler(n)<<endl; return 0; }
欧拉定理:
若a与n互质,则 aφ(n)%n≡1也就是a的欧拉函数的n次方模n同余与1
费马定理: 当n是质数的时候: an-1%n≡1
标签:费马,int,res,定理,long,欧拉,函数 From: https://www.cnblogs.com/o-Sakurajimamai-o/p/17496086.html