結果
| 問題 |
No.14 最小公倍数ソート
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 2025-05-14 13:17:16 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 4,531 ms / 5,000 ms |
| コード長 | 6,417 bytes |
| コンパイル時間 | 850 ms |
| コンパイル使用メモリ | 83,948 KB |
| 実行使用メモリ | 7,844 KB |
| 最終ジャッジ日時 | 2025-05-14 13:19:36 |
| 合計ジャッジ時間 | 51,424 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 20 |
ソースコード
#include <iostream> // For input/output operations (cin, cout)
#include <vector> // For using std::vector dynamic array
#include <numeric> // Required for std::gcd (available in C++17 standard library)
#include <algorithm> // Required for std::sort and std::swap
#include <utility> // Required for std::pair
// Define a custom gcd function if not using C++17 or later.
// The #if directive checks the version of the C++ standard being used.
#if __cplusplus < 201703L
// Implementation of the Euclidean algorithm for GCD
long long gcd(long long a, long long b) {
while (b != 0) {
long long temp = b;
b = a % b;
a = temp;
}
// GCD is the value of 'a' when 'b' becomes 0
return a;
}
// Define std::gcd equivalent for older standards to maintain compatibility
namespace std {
// Wrapper function that calls the custom gcd implementation
long long gcd(long long a, long long b) {
return ::gcd(a, b); // Use the globally defined gcd function
}
}
#endif
// Custom comparator structure for sorting pairs of {sort_key, original_value}
// The sort key is derived from the LCM calculation, specifically f_k(a_i) = a_i / gcd(a_k, a_i)
struct PairComparator {
// Overload the function call operator '()' to define the comparison logic
bool operator()(const std::pair<long long, long long>& p1, const std::pair<long long, long long>& p2) const {
// p1 represents the pair {f_k(a_i), a_i}
// p2 represents the pair {f_k(a_j), a_j}
if (p1.first != p2.first) {
// If the primary sort keys (f_k values) are different, sort based on these keys.
// Return true if p1's key is less than p2's key, meaning p1 comes first.
return p1.first < p2.first;
} else {
// If the primary sort keys are equal, use the original values (a_i, a_j) as a tie-breaker.
// Return true if p1's original value is less than p2's original value.
return p1.second < p2.second;
}
}
};
int main() {
// Optimize C++ standard streams I/O for potentially faster execution, especially with large inputs.
std::ios_base::sync_with_stdio(false); // Disable synchronization with C stdio
std::cin.tie(NULL); // Untie cin from cout
int N; // Declare variable to store the number of integers
std::cin >> N; // Read the number of integers from standard input
// Declare a vector 'a' of type long long to store the N integers.
// Using long long provides safety against potential arithmetic overflows.
std::vector<long long> a(N);
for (int i = 0; i < N; ++i) {
std::cin >> a[i]; // Read each integer into the vector
}
// Declare a temporary vector 'temp_pairs' to store pairs for sorting in each step.
// Each pair will contain {sort_key, original_value}.
std::vector<std::pair<long long, long long>> temp_pairs;
// The main loop iterates from k = 0 to N-2 (total N-1 steps).
// In step k, elements a[0]...a[k] remain fixed in their positions.
// The subarray a[k+1]...a[N-1] is sorted based on the element a[k].
for (int k = 0; k < N - 1; ++k) {
long long fixed_ak = a[k]; // The element a[k] used as the reference for LCM comparisons.
// Clear the temporary vector to reuse it for the current step's sort operation.
temp_pairs.clear();
// Calculate the number of elements in the subarray that needs to be sorted.
int sub_array_size = N - (k + 1);
// Proceed with sorting only if the subarray is non-empty (has elements).
if (sub_array_size > 0) {
// Reserve memory capacity in the vector equal to the subarray size.
// This can improve performance by avoiding dynamic memory reallocations during push_back operations.
temp_pairs.reserve(sub_array_size);
// Iterate through the elements a[i] of the subarray (from index k+1 to N-1).
// Compute the sort key f_k(a_i) for each element and store the pair {f_k(a_i), a[i]}.
for (int i = k + 1; i < N; ++i) {
long long current_ai = a[i]; // The current element being processed.
// Calculate the greatest common divisor (GCD) of the fixed element a[k] and the current element a[i].
// Use std::gcd if available (C++17), otherwise the custom implementation.
long long common_divisor = std::gcd(fixed_ak, current_ai);
// Calculate the primary sort key f_k(a_i) = a_i / gcd(a_k, a_i).
// Since input values a_i are >= 1, the fixed element a_k will also be >= 1 after the first element.
// Thus, gcd(fixed_ak, current_ai) will always be >= 1, making the division safe.
long long f_k_ai = current_ai / common_divisor;
// Add the computed pair {sort_key, original_value} to the temporary vector.
temp_pairs.push_back({f_k_ai, current_ai});
}
// Sort the vector of pairs using std::sort.
// The custom comparator 'PairComparator' defines the sorting rules (primary key f_k, secondary key original value).
// std::sort typically has an average time complexity of O(M log M), where M is the number of elements.
std::sort(temp_pairs.begin(), temp_pairs.end(), PairComparator());
// After sorting the pairs, update the original array 'a' in place.
// The elements in the subarray a[k+1]...a[N-1] are replaced by the sorted sequence.
// The sorted sequence consists of the original values (second component of the pairs) in their new order.
for (int i = 0; i < temp_pairs.size(); ++i) {
// Place the i-th element of the sorted sequence into a[k+1+i].
a[k + 1 + i] = temp_pairs[i].second;
}
}
}
// After completing all N-1 steps, output the final state of the array 'a'.
for (int i = 0; i < N; ++i) {
// Print each element followed by a space, but avoid a trailing space after the last element.
std::cout << a[i] << (i == N - 1 ? "" : " ");
}
// Print a newline character at the end of the output line.
std::cout << std::endl;
return 0; // Return 0 to indicate successful program execution.
}
qwewe