- I avoided using floating point numbers and multiplied them by 10^9 to make them integers.
- The problem condition would be “Multiply an integer by a multiple of 10^18.”
- Calculate how many times each number is divisible by 2 (P2) and how many times each number is divisible by 5 (P5).
P2[i] + P2[j] > 17 and P5[i] + P5[j] > 17
then “multiply by 10^18” python
def solve1(N, AS):
ret = 0
P2 = []
P5 = []
for i in range(N):
p2 = 0
p5 = 0
x = AS[i]
while x % 2 == 0:
p2 += 1
x //= 2
while x % 5 == 0:
p5 += 1
x //= 5
P2.append(p2)
P5.append(p5)
for i in range(N):
for j in range(i + 1, N):
if P2[i] + P2[j] > 17 and P5[i] + P5[j] > 17:
ret += 1
return ret
This will AC for small data, but TLE for large data.
- Since there are up to 200,000 in number, the method of comparing them one by one is on the order of 10 billion, so it’s a TLE.
- There should not be a double loop of N
- Pre-processing allows this to be done in a single loop.
- That is, given
P2[i], P5[i]
, it is sufficient to know “the number of j’s satisfyingP2[i] + P2[j] > 17 and P5[i] + P5[j] > 17
” without looping - → Create [frequency table
- According to the description, that alone would be AC.
- The width of the frequency distribution table is at most 19
- Because there’s no need to distinguish between the 18 squares and above.
- The number of calculations is about 200,000 x 400, which is narrow enough
- The width of the frequency distribution table is at most 19
- But I didn’t notice, and I got even more creative.
- By calculating the cumulative sum in advance, the “number of j’s satisfying
P2[i] + P2[j] > 17 and P5[i] + P5[j] > 17
” can be obtained without even a loop in the frequency table. - With Numpy, Cumulative sum of two-dimensional arrays is also easy python
- By calculating the cumulative sum in advance, the “number of j’s satisfying
for i in range(19, 0, -1):
P[i - 1] += P[i]
for i in range(19, 0, -1):
P[:, i - 1] += P[:, i]
- Now you can ask for it in a single loop. python
for i in range(N):
ret += P[18 - P2[i], 18 - P5[i]]
- But this is not the correct answer and needs to be corrected.
- First, both P2 and P5 have counted “themselves” as a pair for numbers over 9, so subtract that
- As for the rest, both ij and ji pairs are counted, so divide by 2.
- This will make it right.
python
def solve(N, AS):
import numpy as np
ret = 0
P2 = []
P5 = []
P = np.zeros((20, 20), dtype=np.int)
for i in range(N):
p2 = 0
p5 = 0
x = AS[i]
while x % 2 == 0:
p2 += 1
x //= 2
while x % 5 == 0:
p5 += 1
x //= 5
if p2 > 18:
p2 = 18
P2.append(p2)
P5.append(p5)
P[p2, p5] += 1
for i in range(19, 0, -1):
P[i - 1] += P[i]
for i in range(19, 0, -1):
P[:, i - 1] += P[:, i]
for i in range(N):
ret += P[18 - P2[i], 18 - P5[i]]
ret -= P[9, 9]
ret //= 2
return ret
This page is auto-translated from /nishio/AGC047A using DeepL. If you looks something interesting but the auto-translated English is not good enough to understand it, feel free to let me know at @nishio_en. I’m very happy to spread my thought to non-Japanese readers.