给出定义:
欧拉函数定义为不超过n且与n互素的正整数的个数。
有以下性质:
- 设p和q是互素的正整数,有 。
- 若n为正整数,那么 。
利用欧拉函数我们可以推导出欧拉定理,即
,其中m是一个正整数,a为整数,且a与m互素。
欧拉定理可用于求大数的模,求解线性同余方程等。此外,欧拉定理的扩展可以用来实现降幂。现给出扩展欧拉定理:
此外,由于欧拉函数为积性函数,所以可以用欧拉筛在时间复杂度下求解。此外,更快的方式为杜教筛,时间复杂度为。
例题:仪仗队(洛谷 P2158)
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6;
bool vst[N];
int prm[N],cnt,phi[N],sum[N];
void sieve() {
phi[1] = 1;
for(int i = 2; i <= N; i ++) {
if(!vst[i]) {
phi[i] = i - 1;
prm[cnt ++] = i;
}
for(int j = 0; j < cnt; j ++) {
if(i * prm[j] > N) break;
vst[i * prm[j]] = 1;
if(i % prm[j] == 0) {
phi[i * prm[j]] = phi[i] * prm[j];
break;
}
phi[i * prm[j]] = phi[i] * phi[prm[j]];
}
}
}
void slove() {
sieve();
sum[1] = 1;
for(int i = 2; i <= N; i ++) sum[i] = sum[i - 1] + phi[i];
int n;
cin>>n;
if(n == 1) cout<<0<<endl;
else cout<<2 * sum[n - 1] + 1;
}
int main() {
ios::sync_with_stdio(0);
slove();
return 0;
}
例题:【模板】扩展欧拉定理(洛谷 P5091)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll phi = 1;
ll m,a,b;
string bb;
ll ksm(ll a,ll b) {
ll res = 1;
while(b) {
if(b&1) res = (res * a) % m;
a = (a * a) % m,b >>= 1;
}
return res % m;
}
int euler(int n) {
int ans = n;
for(int p = 2; p * p <= n; p ++) {
if(n % p == 0) {
ans = ans / p * (p - 1);
while(n % p == 0) {
n /= p;
}
}
}
if(n != 1) ans = ans / n * (n - 1);
return ans;
}
void slove() {
cin>>a>>m;
phi = euler(m);
cin>>bb;
bool f = false;
for(auto c : bb) {
b = b * 10 + c - '0';
if(b >= phi) f = true,b %= phi;
}
if(f) b += phi;
cout<<ksm(a,b);
}
int main() {
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
slove();
return 0;
}