欧拉函数
定义
对于正整数n,欧拉函数是小于或等于n的正整数中与n互质的数的数目,记作φ(n).
算法思路
既然求解每个数的欧拉函数,都需要知道他的质因子,而不需要个数
因此,我们只需求出他的质因子,然后根据公式:N*(p1-1)/p1*(p2-1)/p2......即可
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll n; int main() { ll i,j; cin>>n; for(i=0;i<n;i++) { ll x; cin>>x; ll ans=x; for(j=2;j<=x/j;j++) { if(x%j==0) { ans=ans*(j-1)/j; while(x%j==0) { x/=j; } } } if(x!=1) ans=ans*(x-1)/x; cout<<ans<<endl; } return 0; }
筛法求欧拉函数
问题
给定一个正整数n,求1~n中每个数的欧拉函数之和。
算法思路
使用线性筛的方法,来求每个数的欧拉函数
#include<bits/stdc++.h> using namespace std; const int N=1e6+10; int n,cnt; bool st[N]; int primes[N]; int phi[N]; void get_eulers() { int i,j; phi[1]=1; for(i=2;i<=n;i++) { if(!st[i]) { primes[cnt++]=i; phi[i]=i-1; for(j=0;primes[j]<=n/i;j++) { st[primes[j]*i]=true; if(i%primes[j]==0) phi[primes[j]*i]=primes[j]*phi[i]; else phi[primes[j]*i]=(primes[j]-1)*phi[i]; } } } int ans=0; for(i=1;i<=n;i++) ans+=phi[i]; cout<<ans<<endl; } int main() { int i,j; cin>>n; get_eulers(); return 0; }
快速幂
#include<bits/stdc++.h> using namespace std; typedef long long ll; void suppow(ll a,ll b,ll p) { ll ans=1; while(b) { if(b&1) ans=(ans*a)%p; a=(a*a)%p; b>>=1; } cout<<ans%p<<endl; } int main() { ll n,a,b,p; cin>>n; while(n--) { cin>>a>>b>>p; suppow(a,b,p); } return 0; }
快速幂求逆元
前提
代码
快速幂求解:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+10; ll supow(ll a,ll b,ll p) { ll ans=1; while(b) { if(b&1) ans=ans*a%p; a=a*a%p; b>>=1; } return ans; } int main() { ll a,p,n; cin>>n; while(n--) { cin>>a>>p; if(a%p!=0) { cout<<supow(a,p-2,p)<<endl; } else puts("impossible"); } return 0; }
扩展欧几里得求逆元
#include <iostream> using namespace std; typedef long long LL; int n; int exgcd(int a, int b, int &x, int &y) { if (!b) { x = 1, y = 0; return a; } int d = exgcd(b, a % b, y, x); y -= a / b * x; return d; } int main() { cin >> n; while (n --) { int a, p, x, y; // if (a < p) swap(a, p); cin >> a >> p; int d = exgcd(a, p, x, y); if (d == 1) cout << ((LL)x + p) % p << endl;//保证x是正数 else puts("impossible"); } return 0; }