Math 给定n的toticent函数的所有实际值之和

Math 给定n的toticent函数的所有实际值之和,math,greatest-common-divisor,Math,Greatest Common Divisor,对于给定的n,如何有效地求一个toticent函数的所有实际值之和。 例如,tot(10)为1,3,7,9=>1+3+7+9=20。 我尝试了下面的暴力方法 int sum = 0; for(int i=1;i<n;i++) { if(gcd(i,n)==1)sum += i; } print(sum) int和=0; 对于(int i=1;i,如果打印出函数的第一个值,则得到: 1、1、3、4、10、6、21、16、27、20、55、24、78、42、60、64、136 查找中

对于给定的n,如何有效地求一个toticent函数的所有实际值之和。 例如,tot(10)为1,3,7,9=>1+3+7+9=20。 我尝试了下面的暴力方法

int sum = 0;
for(int i=1;i<n;i++)
{
    if(gcd(i,n)==1)sum += i;
}
print(sum)
int和=0;

对于(int i=1;i,如果打印出函数的第一个值,则得到:

1、1、3、4、10、6、21、16、27、20、55、24、78、42、60、64、136

查找中的函数,您会发现:“n的totatives之和,即整数到n和互质到n之和”。在这里我们得到一个公式:
n*phi(n)/2
除了
n=1
。这里
phi
是Euler的,Euler自己对其表示了一个快速计算:
n*乘积{不同的素数p除以n}(1-1/p)

将所有内容组合到一些纯Python函数中:

导入数学
def基本系数(n):
如果n==1:
返回[]
如果n%2==0:
返回[2]+素数因子(n//2)
如果n%3==0:
返回[3]+素数因子(n//3)
如果n%5==0:
返回[5]+素数因子(n//5)
对于范围(6,int(math.sqrt(n))+1,6)内的i:
如果n%(i+1)=0:
返回[i+1]+素数因子(n//(i+1))
如果n%(i+5)==0:
返回[i+5]+素数因子(n//(i+5))
返回[n]
def gcd(a、b):
如果b==0:
归还
返回gcd(b,a%b)
定义总和(n):
s=0
对于范围(1,n+1)内的i:
如果gcd(n,i)=1:
s+=i
返回s
def phi(n):
prod=n
对于集合中的i(prime_factors(n)):#转换为集合,因为我们不希望重复
#产品=产品*(1-1/i)
prod=prod*(i-1)//i#重写公式,使其仅适用于整数
返回整数(prod)
定义快速总和(n):
如果n==1:
返回1
返回n*phi(n)//2
打印([范围(1,31)内n的总和(n)])
打印([范围(1,31)内n的快速总和(n)])
n=12345678
打印(快速求和(n))
打印(总和(n))
输出:

[1, 1, 3, 4, 10, 6, 21, 16, 27, 20, 55, 24, 78, 42, 60, 64, 136, 54, 171, 80, 126, 110, 253, 96, 250, 156, 243, 168, 406, 120]
24860442405888
请注意,这里的素因子分解仅通过6k+1和6k+5这两个可能的因子进行。这可以进一步优化,步进模30,其中只需要测试8个因子,可以跳过22个因子。(依此类推,模210=2*3*5*7等)


如果你需要计算很多数字的素数因子,你可以建立一个埃拉托斯烯筛,并将结果保存在一个列表中。这样你只需要逐步通过实素数来找到素数因子。

如果n足够大,那么该技术的一种变体应该可以节省大量时间。试着计算se的前几个元素对n=1,2,3,…进行排序,然后查看在线整数序列百科全书,了解该序列的相关知识。似乎有人已经对其进行了研究。