Skip to content

Commit c7a95b8

Browse files
committed
Runtime: 77 ms (Top 82.13%) | Memory: 16.60 MB (Top 56.38%)
1 parent 08c443b commit c7a95b8

File tree

1 file changed

+8
-64
lines changed

1 file changed

+8
-64
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,13 @@
1-
# For every odd divisor d of n, there's exactly one sum of length d, e.g.
2-
#
3-
# 21 = 3 * 7 = 6 + 7 + 8.
4-
#
5-
# Also, every odd length sum is of this form, since the middle value is average,
6-
# and the sum is just (number of elements) * (average) = d * n/d.
7-
#
8-
# For even length sums, the average is a half-integer
9-
#
10-
# 2 + 3 + 4 + 5 = 4 * 3.5
11-
#
12-
# So n can be written as
13-
#
14-
# n = (even length) * (half-integer average)
15-
# = (2 * c) * (d / 2)
16-
# = c * d
17-
#
18-
# for some arbitrary integer c and odd integer d. So again, any odd d divisor of
19-
# n produces an even length sum, and every even length sum is of this form.
20-
#
21-
# However, we need to ensure that the sum only contains positive integers.
22-
#
23-
# For the first case, the smallest number is n/d - (d-1)/2. For the second case,
24-
# it's (d+1)/2 - n/d.
25-
#
26-
# For all d, exactly one of these is positive, and so every odd divisor
27-
# corresponds to exactly one sum, and all sums are of this form.
28-
#
29-
# Therefore, we need to count the odd divisors.
30-
#
31-
# There's no way I know of doing this without essentially factoring the number.
32-
# So say
33-
#
34-
# n = 2**n0 * p1**n1 * p2**n2 * ... * pk**nk
35-
#
36-
# is the prime decomposition (all p are odd). Then n has
37-
#
38-
# (n1+1) * (n2+1) * ... * (nk+1)
39-
#
40-
# odd divisors.
41-
#
42-
# For the implementation, we search the smallest divisor, which is neccessarily
43-
# prime and divide by it as often as possible (and count the divisions). If
44-
# after that p**2 > n, we know that n itself is prime.
45-
#
46-
# Complexity is O(sqrt(n)) in bad cases (if n is prime), but can be much better
47-
# if n only has small prime factors, e.g. for n = 3**k it's O(k) = O(log(n)).
1+
// Runtime: 77 ms (Top 82.13%) | Memory: 16.60 MB (Top 56.38%)
482

493
class Solution:
504
def consecutiveNumbersSum(self, n: int) -> int:
51-
while n % 2 == 0:
52-
# Kill even factors
53-
n //= 2
54-
result = 1
55-
p = 3
56-
while n != 1:
57-
count = 1
58-
while n % p == 0:
59-
n //= p
60-
count += 1
61-
result *= count
62-
if p**2 >= n:
63-
# Rest of n is prime, stop here
64-
if n > p:
65-
# We have not counted n yet
66-
result *= 2
5+
csum=0
6+
result=0
7+
for i in range(1,n+1):
8+
csum+=i-1
9+
if csum>=n:
6710
break
68-
p += 2
11+
if (n-csum)%i==0:
12+
result+=1
6913
return result

0 commit comments

Comments
 (0)