|
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%) |
48 | 2 |
|
49 | 3 | class Solution:
|
50 | 4 | 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: |
67 | 10 | break
|
68 |
| - p += 2 |
| 11 | + if (n-csum)%i==0: |
| 12 | + result+=1 |
69 | 13 | return result
|
0 commit comments