We can preprocess the array by setting each a_i
to a_i
modulo d
.
We're asked for a sum of three numbers
a_i + a_j + a_k
congruent to 0
modulo d
.
Well gosh, that's a hard problem!
What would be an easier one?
Suppose that a_i
is already fixed, we can't change it.
Well now we only have two numbers to worry about.
What must they sum to?
a_j + a_k
has to be -a_i
modulo d
.
Hmmm, still don't know the answer, do we?
But we're getting close.
Fix a_j
, and now we need merely pick suitable a_k
.
Scan and declare a match if a_k
is -a_i - a_j
modulo d
, FTW.
Create a sorted index, with linear cost:
pairs = sorted((val, i) for i, val in enumerate(arr))
Now finding a desired a_k
costs log2(len(arr)).
This is a good match for the sorted containers library. Total cost will still be O(N ** 2 ×ばつ log(N)).
If we're willing to spend quadratic storage and time, I suppose
that sorting (sum2, j, k)
tuples, where sum2 = (a_j + a_k) % d
,
might be helpful.
That knocks the scanning cost down to O(N ×ばつ log(N ** 2)),
but alas the quadratic cost of creating those tuples would dominate.
Hmmm, no need to sort.
We can allocate a list of length d
where each element is a list of tuples.
That way we just ask for a_k
in O(1) constant time,
without need of binary search.
We can preprocess the array by setting each a_i
to a_i
modulo d
.
We're asked for a sum of three numbers
a_i + a_j + a_k
congruent to 0
modulo d
.
Well gosh, that's a hard problem!
What would be an easier one?
Suppose that a_i
is already fixed, we can't change it.
Well now we only have two numbers to worry about.
What must they sum to?
a_j + a_k
has to be -a_i
modulo d
.
Hmmm, still don't know the answer, do we?
But we're getting close.
Fix a_j
, and now we need merely pick suitable a_k
.
Scan and declare a match if a_k
is -a_i - a_j
modulo d
, FTW.
Create a sorted index, with linear cost:
pairs = sorted((val, i) for i, val in enumerate(arr))
Now finding a desired a_k
costs log2(len(arr)).
This is a good match for the sorted containers library. Total cost will still be O(N ** 2 ×ばつ log(N)).
If we're willing to spend quadratic storage and time, I suppose
that sorting (sum2, j, k)
tuples, where sum2 = (a_j + a_k) % d
,
might be helpful.
That knocks the scanning cost down to O(N ×ばつ log(N ** 2)),
but alas the quadratic cost of creating those tuples would dominate.
We can preprocess the array by setting each a_i
to a_i
modulo d
.
We're asked for a sum of three numbers
a_i + a_j + a_k
congruent to 0
modulo d
.
Well gosh, that's a hard problem!
What would be an easier one?
Suppose that a_i
is already fixed, we can't change it.
Well now we only have two numbers to worry about.
What must they sum to?
a_j + a_k
has to be -a_i
modulo d
.
Hmmm, still don't know the answer, do we?
But we're getting close.
Fix a_j
, and now we need merely pick suitable a_k
.
Scan and declare a match if a_k
is -a_i - a_j
modulo d
, FTW.
Create a sorted index, with linear cost:
pairs = sorted((val, i) for i, val in enumerate(arr))
Now finding a desired a_k
costs log2(len(arr)).
This is a good match for the sorted containers library. Total cost will still be O(N ** 2 ×ばつ log(N)).
If we're willing to spend quadratic storage and time, I suppose
that sorting (sum2, j, k)
tuples, where sum2 = (a_j + a_k) % d
,
might be helpful.
That knocks the scanning cost down to O(N ×ばつ log(N ** 2)),
but alas the quadratic cost of creating those tuples would dominate.
Hmmm, no need to sort.
We can allocate a list of length d
where each element is a list of tuples.
That way we just ask for a_k
in O(1) constant time,
without need of binary search.
We can preprocess the array by setting each a_i
to a_i
modulo d
.
We're asked for a sum of three numbers
a_i + a_j + a_k
congruent to 0
modulo d
.
Well gosh, that's a hard problem!
What would be an easier one?
Suppose that a_i
is already fixed, we can't change it.
Well now we only have two numbers to worry about.
What must they sum to?
a_j + a_k
has to be -a_i
modulo d
.
Hmmm, still don't know the answer, do we?
But we're getting close.
Fix a_j
, and now we need merely pick suitable a_k
.
Scan and declare a match if a_k
is -a_i - a_j
modulo d
, FTW.
Create a sorted index, with linear cost:
pairs = sorted((val, i) for i, val in enumerate(arr))
Now finding a desired a_k
costs log2(len(arr)).
This is a good match for the sorted containers library. Total cost will still be O(N ** 2 ×ばつ log(N)).
If we're willing to spend quadratic storage and time, I suppose
that sorting (sum2, j, k)
tuples, where sum2 = (a_j + a_k) % d
,
might be helpful.
That knocks the scanning cost down to O(N ×ばつ log(N ** 2)),
but alas the quadratic cost of creating those tuples would dominate.
We can preprocess the array by setting each a_i
to a_i
modulo d
.
We're asked for a sum of three numbers
a_i + a_j + a_k
congruent to 0
modulo d
.
Well gosh, that's a hard problem!
What would be an easier one?
Suppose that a_i
is already fixed, we can't change it.
Well now we only have two numbers to worry about.
What must they sum to?
a_j + a_k
has to be -a_i
modulo d
.
Hmmm, still don't know the answer, do we?
But we're getting close.
Fix a_j
, and now we need merely pick suitable a_k
.
Scan and declare a match if a_k
is -a_i - a_j
modulo d
, FTW.
Create a sorted index, with linear cost:
pairs = sorted((val, i) for i, val in enumerate(arr))
Now finding a desired a_k
costs log2(len(arr)).
This is a good match for the sorted containers library. Total cost will still be O(N ** 2 ×ばつ log(N)).
We can preprocess the array by setting each a_i
to a_i
modulo d
.
We're asked for a sum of three numbers
a_i + a_j + a_k
congruent to 0
modulo d
.
Well gosh, that's a hard problem!
What would be an easier one?
Suppose that a_i
is already fixed, we can't change it.
Well now we only have two numbers to worry about.
What must they sum to?
a_j + a_k
has to be -a_i
modulo d
.
Hmmm, still don't know the answer, do we?
But we're getting close.
Fix a_j
, and now we need merely pick suitable a_k
.
Scan and declare a match if a_k
is -a_i - a_j
modulo d
, FTW.
Create a sorted index, with linear cost:
pairs = sorted((val, i) for i, val in enumerate(arr))
Now finding a desired a_k
costs log2(len(arr)).
This is a good match for the sorted containers library. Total cost will still be O(N ** 2 ×ばつ log(N)).
If we're willing to spend quadratic storage and time, I suppose
that sorting (sum2, j, k)
tuples, where sum2 = (a_j + a_k) % d
,
might be helpful.
That knocks the scanning cost down to O(N ×ばつ log(N ** 2)),
but alas the quadratic cost of creating those tuples would dominate.
We can preprocess the array by setting each a_i
to a_i
modulo d
.
We're asked for a sum of three numbers
a_i + a_j + a_k
congruent to 0
modulo d
.
Well gosh, that's a hard problem!
What would be an easier one?
Suppose that a_i
is already fixed, we can't change it.
Well now we only have two numbers to worry about.
What must they sum to?
a_j + a_k
has to be -a_i
modulo d
.
Hmmm, still don't know the answer, do we?
But we're getting close.
Fix a_j
, and now we need merely pick suitable a_k
.
Scan and declare a match if a_k
is -a_i - a_j
modulo d
, FTW.
Create a sorted index, with linear cost:
pairs = sorted((val, i) for i, val in enumerate(arr))
Now finding a desired a_k
costs log2(len(arr)).
This is a good match for the sorted containers library. Total cost will still be O(N ** 2 ×ばつ log(N)).
We're asked for a sum of three numbers
a_i + a_j + a_k
congruent to 0
modulo d
.
Well gosh, that's a hard problem!
What would be an easier one?
Suppose that a_i
is already fixed, we can't change it.
Well now we only have two numbers to worry about.
What must they sum to?
a_j + a_k
has to be -a_i
modulo d
.
Hmmm, still don't know the answer, do we?
But we're getting close.
Fix a_j
, and now we need merely pick suitable a_k
.
Scan and declare a match if a_k
is -a_i - a_j
modulo d
, FTW.
We can preprocess the array by setting each a_i
to a_i
modulo d
.
We're asked for a sum of three numbers
a_i + a_j + a_k
congruent to 0
modulo d
.
Well gosh, that's a hard problem!
What would be an easier one?
Suppose that a_i
is already fixed, we can't change it.
Well now we only have two numbers to worry about.
What must they sum to?
a_j + a_k
has to be -a_i
modulo d
.
Hmmm, still don't know the answer, do we?
But we're getting close.
Fix a_j
, and now we need merely pick suitable a_k
.
Scan and declare a match if a_k
is -a_i - a_j
modulo d
, FTW.
Create a sorted index, with linear cost:
pairs = sorted((val, i) for i, val in enumerate(arr))
Now finding a desired a_k
costs log2(len(arr)).
This is a good match for the sorted containers library. Total cost will still be O(N ** 2 ×ばつ log(N)).