欧拉函数 笔记

复习:欧拉筛

int cnt,prime[10000005],n;
bool vis[100000005];
void olaprime(){
    vis[1]=1;
    for(int i=2;i<=n;i++){
		if(!vis[i]){
			prime[++cnt]=i;
		}
		for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
			vis[i*prime[j]]=1;
			if(i%prime[j]==0){
				break;
			}
		}
	}
}

线性筛模板

题目描述

给定一个范围 [ 1 , n ] [1,n] [1,n] ,有 q q q 次询问,每次输出第 k k k 小的素数。

输入描述

第一行两个正整数 n , q ( 2 ≤ n ≤ 1 e ​ 8 ​​ , 1 ≤ q ≤ 1 e ​ 6 ​​ ) n,q(2≤n≤1e​8​​ ,1≤q≤1e​6​​ ) n,q(2n1e​8​​,1q1e​6​​)
接下来 q q q 行,代表 q q q 次询问。每次询问给定一个正整数 k k k ,保证 k k k 合理。

输出描述

对于每次询问,输出第 k k k 小的素数。

样例输入

100 5
1
2
3
4
5

样例输出

2
3
5
7
11

#include
using namespace std;
int cnt,prime[10000005],n,q,k;
bool vis[100000005];
void olaprime(){
    vis[1]=1;
    for(int i=2;i<=n;i++){
		if(!vis[i]){
			prime[++cnt]=i;
		}
		for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
			vis[i*prime[j]]=1;
			if(i%prime[j]==0){
				break;
			}
		}
	}
}
int main(){
    scanf("%d%d",&n,&q);
    olaprime();
    for(int i=1;i<=q;i++){
        scanf("%d",&k);
        printf("%d\n",prime[k]);
    }
    return 0;
}

数论函数

积性函数

对于两个互质的正整数 n , m n,m n,m 如果满足:

f ( m n ) = f ( m ) f ( n ) f(mn)=f(m)f(n) f(mn)=f(m)f(n)

那么 f ( x ) f(x) f(x)积性函数

如果任意 n , m n,m n,m 都满足,哪么称之为 完全积性函数

f ( x ) = 1 f(x)=1 f(x)=1就是一个完全积性函数,这个函数是一个常见的数论函数,叫做常数函数

以下函数都是数论函数

f ( x ) = [ x = 1 ] f(x)=[x=1] f(x)=[x=1]完全积性函数

f ( n ) × f ( m ) = { 1          n = 1 , m = 1 0                         e l s e = f ( n m ) f(n)\times f(m)=\left\{ \begin{matrix} 1~~~~~~~~ n=1,m=1 \\ 0 ~~~~~~~~~~~~~~~~~~~~~~~else \end{matrix}\right. =f(nm) f(n)×f(m)={1        n=1,m=10                       else=f(nm)

这个函数叫做单位函数一般写为: ϵ ( n ) = [ n = 1 ] \epsilon(n)=[n=1] ϵ(n)=[n=1]

f k ( n ) = ∑ d ∣ n d k f_{k}(n)=\sum_{d|n}{}{d^{k}} fk(n)=dndk 这是一个积性函数,但不是完全积性函数

这种函数被称作除数函数。记作:

σ k ( n ) = ∑ d ∣ n d k \sigma_{k}(n)=\sum_{d|n}d^{k} σk(n)=dndk

f ( n ) = ∑ i = 1 n [ g c d ( i , n ) = 1 ] f(n)=\sum_{i=1}^{n}{[gcd(i,n)=1]} f(n)=i=1n[gcd(i,n)=1]积性函数,即欧拉函数,通常被写作:
ϕ ( n ) = ∑ i = 1 n [ g c d ( i , n ) = 1 ] \phi(n)=\sum_{i=1}^{n}{[gcd(i,n)=1]} ϕ(n)=i=1n[gcd(i,n)=1]

求的就是小于等于 n n n 与其互质的数的个数

又写作:
ϕ ( n ) = n ( 1 − 1 p 1 ) ( 1 − 1 p 2 ) . . . ( 1 − 1 p k ) \phi(n)=n(1-\frac{1}{p_1})(1-\frac{1}{p_2})...(1-\frac{1}{p_k}) ϕ(n)=n(1p11)(1p21)...(1pk1)

莫比乌斯函数等也是积性函数

欧拉函数

n n n 可以写成如下形式:
n = p 1 k 1 p 2 k 2 . . . p m k m n=p_1^{k_1}p_2^{k_2}...p_m^{k_m} n=p1k1p2k2...pmkm

可得如下性质:
ϕ ( p k ) = p k − p k − 1 \phi(p^k)=p^k-p^{k-1} ϕ(pk)=pkpk1

又因为其为积性函数,我们可以得到:
ϕ ( n ) \phi(n) ϕ(n)
= ϕ ( p 1 k 1 p 2 k 2 . . . p m k m ) =\phi(p_1^{k_1}p_2^{k_2} ... p_m^{k_m}) =ϕ(p1k1p2k2...pmkm)
= ϕ ( p 1 k 1 ) ϕ ( p 2 k 2 ) . . . ϕ ( p m k m ) =\phi(p_1^{k_1})\phi(p_2^{k_2}) ...\phi(p_m^{k_m}) =ϕ(p1k1)ϕ(p2k2)...ϕ(pmkm)
= ( p 1 k 1 − p 1 k 1 − 1 ) ( p 2 k 2 − p 2 k 2 − 1 ) . . . ( p m k m − p m k m − 1 ) =(p_1^{k_1}-p_1^{k_1-1})(p_2^{k_2}-p_2^{k_2-1})...(p_m^{k_m}-p_m^{k_m-1}) =(p1k1p1k11)(p2k2p2k21)...(pmkmpmkm1)
= p 1 k 1 p 2 k 2 . . . p m k m ∏ i = 1 m ( 1 − 1 p i ) =p_1^{k_1}p_2^{k_2}...p_m^{k_m}\prod_{i=1}^{m}{(1-\frac{1}{p_i})} =p1k1p2k2...pmkmi=1m(1pi1)
= n ∏ i − 1 m ( 1 − 1 p i ) =n\prod_{i-1}^{m}{(1-\frac{1}{p_i})} =ni1m(1pi1)
= n ∏ i − 1 m p i − 1 p i =n\prod_{i-1}^{m}{\frac{p_i-1}{p_i}} =ni1mpipi1

欧拉定理

a a a m m m 互质,则:
a ϕ ( m ) ≡ 1 ( m o d   m ) a^{\phi(m)}\equiv 1(mod~m) aϕ(m)1(mod m)

这就是欧拉定理

如果 p p p 是质数,那么:
a p − 1 ≡ 1 ( m o d   p ) a^{p-1}\equiv1(mod~p) ap11(mod p)

例题

1.求欧拉函数

题目描述

输入 n n n ,请输出 ϕ ( n ) ϕ(n) ϕ(n) 的值。
输入描述

多组输入。每组输入一个整数 n ( n ≤ 1 e ​ 9 ) n(n≤1e​9) n(n1e​9) 。当输入的 n = 0 n=0 n=0 时结束。

输出描述

对于每组输入,输出一个整数表示答案。

样例输入

7
12
0

样例输出

6
4

#include
using namespace std;
long long n,ans;
void fun(){
	int m=sqrt(n);
	ans=n;
	for(int i=2;i<=m;i++){
		if(n%i==0){
			ans=ans/i*(i-1);
			while(n%i==0){
				n/=i;
			}
		}
	}
	if(n>1){
		ans=ans/n*(n-1);
	}
	return ;
}
int main(){
	while(scanf("%lld",&n)&&n!=0){
		fun();
		printf("%lld\n",ans);
	}
    return 0;
}

你可能感兴趣的:(笔记)