欧拉函数
- 定义:在数论,对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目.
- 引理:
证明用容斥原理
例题
给定 n 个正整数 ai,请你求出每个数的欧拉函数。
欧拉函数的定义
1∼N 中与 N 互质的数的个数被称为欧拉函数,记为 ϕ(N)。
若在算数基本定理中,
N
=
p
1
a
1
p
2
a
2
…
p
m
a
m
N= p_1^{a1} p_2^{a_2}…p_m^{a_m}
N=p1a1p2a2…pmam,则:
ϕ
(
N
)
=
N
×
p
1
−
1
p
1
×
p
2
−
1
p
2
×
…
×
p
m
−
1
p
m
ϕ(N) = N×\frac{p_1−1}{p1}×\frac{p_2−1}{p2}×…×\frac{p_m−1}{pm}
ϕ(N)=N×p1p1−1×p2p2−1×…×pmpm−1
输入格式
第一行包含整数 n。
接下来 n 行,每行包含一个正整数 ai。
输出格式
输出共 n 行,每行输出一个正整数 ai 的欧拉函数。
数据范围
1≤n≤100,
1≤ai≤2×10^9
输入样例:
3
3
6
8
输出样例:
2
2
4
n = int(input())
for i in range(n) :
a = int(input())
res = a
i = 2
while i <= a // i :
if a % i == 0 :
res = res // i * (i - 1)
while a % i == 0 :
a //= i
i += 1
if a > 1 :
res = res // a * (a - 1)
print(res)
筛法求欧拉函数
- 算法思路:
在筛质数的同时,质数的欧拉函数为 f ( n ) = n − 1 f(n) = n - 1 f(n)=n−1,在将合数筛出时计算合数的欧拉函数
给定一个正整数 n,求 1∼n 中每个数的欧拉函数之和。
输入格式
共一行,包含一个整数 n。
输出格式
共一行,包含一个整数,表示 1∼n 中每个数的欧拉函数之和。
数据范围
1≤n≤106
输入样例:
6
输出样例:
12
N = 100010
prime = []
eula = [0] * N
st = [True] * N
def sum_eula(x) :
for i in range(1, x + 1) :
if i == 1 :
eula[i] = 1
continue
if st[i] :
prime.append(i)
eula[i] = i - 1
for j in prime :
if i * j > x :
break
st[i * j] = False
if i % j == 0 :
eula[i * j] = j * eula[i] # 已经计算过j的质因子
break
eula[i * j] = (j - 1) * eula[i] # j * eula[i] * (1 - 1/j) 第一次计算为j的质因子
res = 0
for i in range(1, x + 1) :
res += eula[i]
return res
n = int(input())
print(sum_eula(n))
可见的点
在一个平面直角坐标系的第一象限内,如果一个点 (x,y) 与原点 (0,0)
的连线中没有通过其他任何点,则称该点在原点处是可见的。
例如,点 (4,2) 就是不可见的,因为它与原点的连线会通过点 (2,1)。部分可见点与原点的连线如下图所示:
编写一个程序,计算给定整数 N 的情况下,满足 0≤x,y≤N 的可见点 (x,y) 的数量(可见点不包括原点)。
输入格式
第一行包含整数 C,表示共有 C 组测试数据。
每组测试数据占一行,包含一个整数 N。
输出格式
每组测试数据的输出占据一行。
应包括:测试数据的编号(从 1 开始),该组测试数据对应的 N 以及可见点的数量。
同行数据之间用空格隔开。
数据范围
1≤N,C≤1000
输入样例:
4
2
4
5
231
输出样例:
1 2 5
2 4 13
3 5 21
4 231 32549
思路
坐标上的每个点,都满足
y
=
k
x
y = kx
y=kx,对于可见的点来说,应该是这条线上距离原点最近的点。假设此时最近的点时
(
x
0
,
y
0
)
(x_0, y_0)
(x0,y0),那么这个点满足什么性质呢?首先
k
=
y
i
x
i
k = \frac{y_i}{x_i}
k=xiyi,其中
(
x
i
,
y
i
)
(x_i, y_i)
(xi,yi)必须都取的足够小,才能可见。显然,
(
x
0
,
y
0
)
(x_0, y_0)
(x0,y0)应该是互质才满足条件。
最终的答案应该是1~N中所有的质数对。
代码
N = 1010
st = [False] * N
primes = []
phi = [0] * N
def init(n) :
phi[1] = 1
for i in range(2, n + 1) :
if not st[i] :
phi[i] = i - 1
primes.append(i)
for j in primes :
if i * j > n :
break
st[i * j] = True
if i % j == 0 :
phi[i * j] = j * phi[i]
break
phi[i * j] = (j - 1) * phi[i]
T = int(input())
init(N - 1)
for t in range(T) :
n = int(input())
res = 1
for i in range(1, n + 1) :
res += phi[i] * 2
print(t + 1, n, res)
欧拉定理
设 a , m ∈ N + a, m \in N^+ a,m∈N+,且 g c d ( a , m ) = 1 gcd(a, m) = 1 gcd(a,m)=1,则我们有: a Ψ ( m ) ≡ 1 ( m o d m ) a^{\varPsi(m)}\equiv 1(mod\ m) aΨ(m)≡1(mod m)
其中 Ψ ( m ) \varPsi(m) Ψ(m)称为对模m缩系的元素个数。
总结
梦回密码学,欧拉函数还是挺简单的,质数是最基础的。欧拉函数是求质数对的好工具。