These days I have studied the Mobius inversion that has troubled me for a long time. Although I have not learned very well now, I will just write a summary. Hey, I didn’t learn how to master it. It seems to be very good. Under-beat, Euler functions are now systematically sorted out.
One, Euler function
1. Definition: **In number theory, for a positive integer n, Euler's function is the number of positive integers less than n that are relatively prime to n (φ(1)=1). **This function is named after its first researcher Euler's totient function (Euler's totient function), it is also called Euler's totient function, φ function, Euler quotient, etc. For example, φ(8)=4, because 1, 3, 5, and 7 are all relatively prime to 8. The facts derived from Euler's function in ring theory and Lagrange's theorem constitute the proof of Euler's theorem.
Let n be a positive integer, and use φ(n) to represent the number of positive integers that do not exceed n and are relatively prime to n. The Euler function value of n is called
φ: N→N, n→φ(n) is called Europe Pull function.
2. Function content:
general formula:
where p1, p2...pn are all prime factors of x, and x is an integer other than 0.
As for some properties of Euler's function, please refer to the following blog:
Inverse element blog
3. After that, several codes for seeking Euler function are given: (It is recommended to read this blog)
(1) Code for seeking Euler function by sieve method:
//筛法欧拉函数
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int N=3e6+10;
int euler[N];
void getEuler()
{
memset(euler,0,sizeof(euler));
euler[1]=1;
for(int i=2; i<N; i++)
{
if(euler[i]==0)
{
for(int j=i; j<N; j++)
{
if(euler[j]==0)
euler[j] = j;
euler[j] = euler[j]/i*(i-1);
}
}
}
}
int main()
{
getEuler();
int n;
cin>>n;
cout<<euler[n]<<endl;
return 0;
}
(2) Find the Euler function of a single number:
//求单个数的欧拉函数 也就是所谓的直接求
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define ll long long
const int N=3e6+10;
ll eular(ll n)
{
ll ans = n;
for (int i = 2; i*i <=n; i++)
{
if(n%i==0)
{
ans-=ans/i;
while( n % i == 0)
n /= i;
}
}
if(n>1)
ans -= ans/n;
return ans;
}
int main()
{
int n;
cin>>n;
cout<<eular(n)<<endl;
return 0;
}
(3) Linear sieve to find Euler function (at the same time get Euler function and prime number table):
//线性筛的时间复杂度为O(n)
//
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define ll long long
const int N=3e6+10;
bool check[N];
int phi[N];//
int prime[N];//素数
int tot;
void phi_and_prime_table(int x)
{
memset(check,false,sizeof(check));
phi[1]=1;
tot = 0;
for(int i = 2; i <= x; i++)
{
if( !check[i])//i是素数
{
prime[tot++] = i;
phi[i] =i-1;
}
for(int j=0; j < tot; j++)
{
if(i* prime[j]>x)
break;
check[i*prime[j]]=true;
if( i % prime[j] == 0)
{
phi[i*prime[j]]=phi[i] * prime[j];
break;
}
else
{
phi[i *prime[j]]=phi[i] * (prime[j]-1);
}
}
}
}
int main()
{
int n;
cin>>n;
phi_and_prime_table(n);
cout<<phi[n]<<endl;
return 0;
}
(4) Decompose prime factors to find Euler's function: detailed code is not given here
The above are the knowledge points and code templates of Euler functions, and then I will introduce the Mobius inversion
2. Mobius inversion
1. Theorem: F(n) and f(n) are two functions defined on the set of non-negative integers, and if the conditions
are met , we get the conclusion
Among them, u(d) is the Möbius function, defined as follows:
(1) If d=1, then u(d)=1
(2) If d=p1 p2 p3····*pk, pi are all mutual Different prime numbers, then u(d)=(-1)^k
(3) In other cases u(d)=0
The u(d) function has the following common properties:
(1) For any positive integer n
(2) For any positive integer n
2. Proof:
3. Find the Möbius function through linear screening:
//线性筛求莫比乌斯反演
//
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define ll long long
const int N=3e6+10;
ll mob[N];
ll vis[N];
ll prime[N];//素数
ll cnt;
void Mobius()
{
memset(prime,0,sizeof(prime));
memset(mob,0,sizeof(mob));
memset(vis,0,sizeof(vis));
mob[1] = 1;
cnt = 0;
for(ll i = 2; i <N; i++)
{
if( !vis[i])
{
prime[cnt++] = i;
mob[i]=-1;
}
for(ll j=0; j < cnt&&i*prime[j]<N; j++)
{
vis[i*prime[j]]=1;
if(i%prime[j])
mob[i*prime[j]]=-mob[i];
else{
mob[i*prime[j]]=0;break;}
}
}
}
int main()
{
int n;
Mobius();
cin>>n;
cout<<mob[n]<<endl;
return 0;
}
Well, I’ll write this first, and I’ll come back to add when I have a deeper understanding these days.