数论——欧拉函数

欧拉函数

  1. 定义:在数论,对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目.
  2. 引理:在这里插入图片描述

证明用容斥原理

例题

给定 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=p1a1p2a2pmam,则:
ϕ ( 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×p1p11×p2p21××pmpm1
输入格式
第一行包含整数 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)

筛法求欧拉函数

  1. 算法思路:

在筛质数的同时,质数的欧拉函数为 f ( n ) = n − 1 f(n) = n - 1 f(n)=n1,在将合数筛出时计算合数的欧拉函数

给定一个正整数 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,mN+,且 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缩系的元素个数。

总结

梦回密码学,欧拉函数还是挺简单的,质数是最基础的。欧拉函数是求质数对的好工具。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值