### Hint:
* Bài toán yêu cầu một cách sắp xếp tuỳ chỉnh.
* Trong C++ ta có thể lưu mỗi bộ ba dưới dạng:
```cpp
pair<ll, pair<ll, ll>>
```
tức là `(x, (y, z))`.
* Sau đó cài đặt một **hàm so sánh** (comparator) để định nghĩa quy tắc sắp xếp.
Quy tắc sắp xếp:
* Nếu `x1 < x2` thì bộ thứ nhất đứng trước.
* Nếu `x1 == x2` thì so sánh `y1 < y2`.
* Nếu tiếp tục bằng nhau thì so sánh `z1 < z2`.
Đây chính là **sắp xếp từ điển (lexicographical order)**.
---
### Code tham khảo:
```cpp
#include <bits/stdc++.h>
#define ll long long
#define name "TASK"
#define TIME (1.0 * clock() / CLOCKS_PER_SEC)
using namespace std;
// Hàm so sánh: sắp xếp từ điển theo (x, y, z)
bool cmp(pair<ll, pair<ll, ll>> p1, pair<ll, pair<ll, ll>> p2) {
if (p1.first != p2.first) return p1.first < p2.first;
if (p1.second.first != p2.second.first) return p1.second.first < p2.second.first;
return p1.second.second < p2.second.second;
}
void solve() {
ll n; cin >> n;
vector<pair<ll, pair<ll, ll>>> a(n);
for (ll i = 0; i < n; i++) {
cin >> a[i].first >> a[i].second.first >> a[i].second.second;
}
sort(a.begin(), a.end(), cmp);
for (auto p : a) {
cout << p.first << " " << p.second.first << " " << p.second.second << "\n";
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
if (fopen(name".INP","r")) {
freopen(name ".INP","r",stdin);
freopen(name ".OUT","w",stdout);
}
solve();
cerr << '\n' << "Time collapsed: " << TIME << '\n';
return 0;
}
```
---
### Độ phức tạp
* Sắp xếp `n` phần tử: `O(n log n)`
* In ra kết quả: `O(n)`
* Tổng: **`O(n log n)`**
---