ZZNUoj 2094 : 正约数之和【n!的因子和】

部署运行你感兴趣的模型镜像

题目描述

我们把f(i)表示为i的正约数的和,而我们要求的是1<=i<=n之间所有i的f(i)之和!

输入

先输入一个正整数T,表示T个这是数据。T(T<=50)
每行输入一个正整数n。(n<10^6)

输出

输出一个数字,表示所求的数。

样例输入

复制
3
5
12
2018

样例输出

复制
21
127
3350309

题意:求n!的因子数之和。

思路:累加n中存在的n/i个以i为因子的数的因子i ,1<= i<= n.

#include<stdio.h>
#include<string.h>
#define LL long long 
LL Judge(int n)
{
	LL sum=n;
	int i;
	for(i = 2; i <= n; i ++)
		sum += (n/i)*i;//在n范围内,是i的整数倍的数有n/i个,则1-n中所有以i为因子的数的总和为(n/i)*i 
	return sum;
}

int main()
{
	int n,t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		printf("%lld\n",Judge(n));
	}
	return 0;
}


您可能感兴趣的与本文相关的镜像

Kotaemon

Kotaemon

AI应用

Kotaemon 是由Cinnamon 开发的开源项目,是一个RAG UI页面,主要面向DocQA的终端用户和构建自己RAG pipeline

<think>根据用户需求,需要计算两个整数的所有公约数。注意不是最大公约数,而是所有公约数。 我们可以先求出两个数的所有公约数,然后求。 方法: 1. 先找到两个数的最大公约数(因为公约数都是最大公约数约数)。 2. 然后找出最大公约数的所有约数(即两数的所有公约数)。 3. 将这些约数。 另一种方法是直接遍历从1到最大公约数(因为公约数不会超过最大公约数),找出最大公约数的所有约数(也就是两数的公约数),然后求。 注意:根据定义,公约数包括1最大公约数本身。 步骤: 步骤1:计算两个数的最大公约数(gcd)。可以使用欧几里得算法(辗转相除法)或者直接使用math.gcd。 步骤2:得到最大公约数g后,求g的所有约数因子)。 步骤3:对得到的约数列表求。 但是注意,题目要求的是两个整数的公约数,所以这些公约数就是最大公约数的所有约数。 示例:比如1218,最大公约数是6,6的约数是1,2,3,6,那么公约数就是1+2+3+6=12。 因此,我们可以先写一个函数求最大公约数(或者直接使用math.gcd),再写一个函数求一个数的所有约数,然后求。 考虑到效率,求约数时不需要遍历到n,只需遍历到sqrt(n)即可。 但是注意:用户要求的是两个整数的公约数,我们不需要分别求两个数的约数再取交集,因为我们已经知道公约数就是最大公约数约数。 因此,我们可以这样实现: 1. 计算gcd(a, b) -> g 2. 计算g的所有约数,并求。 但是,如果两个数的最大公约数是1,那么公约数只有1,就是1。 代码结构: def gcd(a, b): # 计算最大公约数 while b: a, b = b, a % b return a def get_divisors(n): # 求一个数的所有约数因子) divisors = set() for i in range(1, int(n**0.5)+1): if n % i == 0: divisors.add(i) divisors.add(n//i) return divisors def sum_common_divisors(a, b): if a <=0 or b<=0: return "输入必须是整数" g = gcd(a, b) divisors = get_divisors(g) return sum(divisors) 但是注意,题目要求输入两个整数,所以我们可以假设输入为整数,但为了健壮性,可以检查一下。 另外,也可以不单独求所有约数,而是直接遍历1到g(最大公约数),判断是否为g的约数,然后累加。但是当g很大时,这样效率较低。所以使用上述求约数的方法(遍历到平方根)更高效。 根据引用[4]中,有使用递归求最大公约数的方法,但这里我们可以使用更高效的辗转相除法(非递归)。 我们参考上述引用中的方法,比如引用[5]使用了循环求最大公约数(辗转相除法)。 因此,我们按照上述思路编写代码。 注意:公约数包括1最大公约数本身,所以求约数的函数会包括这些数。 编写代码: 首先,定义求最大公约数的函数(使用欧几里得算法)。 然后,定义求一个数的所有约数(为了效率避免重复,使用集合)。 最后,将约数。 但是,用户要求的是“公约数”,所以返回的就是最大公约数的所有约数。 下面我们实现代码。 </think>以下是使用Python计算两个整数所有公约数的方法: ### 算法思路 1. **计算最大公约数(GCD)** 使用辗转相除法(欧几里得算法)求GCD,公式为: $$ \gcd(a,b) = \gcd(b, a \bmod b) \quad \text{直到} \quad b=0 $$ 2. **获取公约数** 所有公约数均为GCD的约数,通过遍历$1$到$\sqrt{\text{gcd}}$找出所有约数。 3. **求** 将所有公约数累加得到最终结果。 ### Python实现代码 ```python def gcd(a, b): """计算最大公约数""" while b: a, b = b, a % b return a def sum_common_divisors(x, y): """计算两个整数的公约数""" g = gcd(x, y) divisors = set() # 遍历1到√g,高效获取所有约数 for i in range(1, int(g**0.5) + 1): if g % i == 0: divisors.add(i) divisors.add(g // i) return sum(divisors) # 输入验证与主逻辑 if __name__ == '__main__': try: a = int(input("输入第一个整数: ")) b = int(input("输入第二个整数: ")) if a <= 0 or b <= 0: raise ValueError("必须输入整数") result = sum_common_divisors(a, b) print(f"{a}{b}的公约数: {result}") except ValueError as e: print(f"错误: {e}") ``` ### 执行示例 ``` 输入第一个整数: 12 输入第二个整数: 18 1218的公约数: 12 ``` **解释**: 1218的公约数为{1, 2, 3, 6},为$1+2+3+6=12$。 ### 关键点说明 1. **辗转相除法**:高效计算GCD(时间复杂度$O(\log n)$)[^1]。 2. **约数遍历优化**:仅需遍历$1$到$\sqrt{\text{gcd}}$,降低时间复杂度至$O(\sqrt{n})$[^2]。 3. **集合去重**:确保约数不重复存储。 ### 备选方案 使用`math.gcd`简化实现(需导入标准库): ```python import math def sum_common_divisors(x, y): g = math.gcd(x, y) return sum(i for i in range(1, g + 1) if g % i == 0) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值