Disclaimer This is an exercise of my course, not from an on going contest.
Problem description
The problem description is very straight forward:
You are given two arrays, A and B, containing n and m elements, correspondingly. The numbers which you need to sort are Ai*Bj , for 1 <= i <= n and 1 <= j <= m. In simple words, every element of the first array should be multipled by every element of the second array.
Let C be a result of this sorting, being a non-decreasing sequence of element. Print the sum of every tenth element of this sequence, that is, C1 + C11 + C21 + ... .
1 <= n,m <= 6000
1 <= Ai,Bj <= 40000
Memory limit: 512MB
Time limit: 2 seconds
My solution so far
First I use Java, using Arrays.sort, given the largest n,m. We will need to sort an array with size of 36000000. Then go through every tenth element in the array to get the sum. This passes 23 test cases, and the rest got TLE.
Then I switch to C++, also use the builtin sort method, and the result is just a little bit better, passes 29 test cases.
My observation
Given this input
4 4
7 1 4 9
2 7 8 11
If we sort two array A and B first then multiply them together, we got
2 8 14 18 7 28 49 63 8 32 56 72 11 44 77 99
which is an array with m sorted subarrays. But I couldn't think of any good solution to merge all of these sorted subarray in O(mn) or somewhere around that. Or we need to look at the problem from a different angle, is there any special properties involve with multiplying every elements of two array together?
Update 1: - using MinHeap - not fast enough. [TLE]
Update 2: - using k ways merge - still not fast enough. [TLE]
Update 3: - I forgot to mention about the range of elements in A and B so I've just updated it.
Update 4: - Radix sort base 256 [Accepted]
Conclusion
Through out this problem, I know more about sorting in general and some useful information of sorting with libraries in Java and C++.
Builtin sort methods in C++ like std::sort is not stable because it is basically a quicksort but when the data format is not favorable for quicksort, then it switches to merge sort, but in general it is the fastest builtin sort of C++ (beside qsort, stable_sort).
For Java, there are 3 types of sort, one with Arrays.sort(primitive[]), which uses merge sort under the hood, Arrays.sort(Object[]) which uses Timsort and Collections.sort which basically calls Arrays.sort to do its heavy processing stuff.
Big thanks to @rcgldr for his radix sort base 256 C++ code, it works like a champ with worse case of 6000*6000 elements, maximum running time is 1.187s.
- Interestingly, the std::sort of C++ only failed on last 3 biggest test cases, it works fine with input of size 6000*3000.