我试图在给定范围a,b a <= b中找到c
的所有除数之和。
我尝试从a
到b
循环并求和c
的所有除数,但这似乎效率不高,因为a和b之间的绝对差可以是10 ^ 9 。
有没有一种方法可以减少这种方法的时间复杂度?
int a, b, c;
cin >> a >> b >> c;
long long sum = 0;
for (int i = a; i <= b; i++) {
if (i % c == 0) {
ans += i;
}
}
cout << sum << endl;
答案 0 :(得分:3)
注意:问题尚不清楚,我们是否需要对除数(在描述中)或可整的整数(在代码示例中)求和。答案总结了可分割的项目。
这很简单。
from
,使from % c == 0 && from >= a
的最小值to
,使to % c == 0 && to <= b
的最大值。
int n = (to - from) / c + 1;
return n * (to + from) / 2;
返回to - from + c
。当to
可能溢出您的类型而from
可能溢出时,请注意边界条件。
要找到from
,请执行以下操作:
if (c < 0) c *= -1; // works unless c == MIN_INT
if (a % c == 0)
from = a;
else if (a >= 0)
from = (a / c * c) + c
else
from = a / c * c;
与to
类似,但是考虑到我们需要四舍五入而不是四舍五入的事实。
此外,需要分别处理a > b
的情况。
这是没有循环,递归或容器的完整代码。它在O(1)中运行:
int a, b, c;
std::cin >> a >> b >> c;
if (!std::cin) {
std::cout << "input error\n";
return 0;
}
if (c < 0) c*= -1;
const int from = [a,c] {
// no rounding needed
if (a % c == 0) return a;
// division rounds down to zero
if (a > 0) return (1 + a / c) * c;
// division rounds up to zero
return a / c * c;
}();
const int to = [b,c] {
// no rounding needed
if (b % c == 0) return b;
// division rounds down to zero
if (b > 0) return (b / c) * c;
// division rounds up to zero
return (b / c - 1) * c;
}();
int64_t sum = 0;
if (from <= to)
{
const int n = (to - from) / c + 1;
sum = n * (to + from) / 2;
}
std::cout << sum << '\n';
答案 1 :(得分:2)
首先确定所有除以c的质数。这将为您留下数字[w,x,y,z ...]的列表。然后,在此列表中保留一个整数表的所有整数倍的哈希表集,这些整数也是除数。
int a, b, c;
cin >> a >> b >> c;
long long sum = 0;
std::vector<int> all_prime_factors = // Get all prime factors of c
std::unordered_set<int> factorSet;
for (int primefactor : all_prime_factors)
{
int factor = primefactor;
while (factor <= b)
{
if (factor % c == 0)
factorSet.insert(factor);
factor += primefactor;
}
}
for (int x : factorSet)
{
sum += x;
}
cout << sum << endl;