結果
問題 |
No.3238 Shadow
|
ユーザー |
![]() |
提出日時 | 2025-08-16 10:48:40 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 54 ms / 2,000 ms |
コード長 | 1,505 bytes |
コンパイル時間 | 2,944 ms |
コンパイル使用メモリ | 279,628 KB |
実行使用メモリ | 7,716 KB |
最終ジャッジ日時 | 2025-08-16 10:48:45 |
合計ジャッジ時間 | 4,886 ms |
ジャッジサーバーID (参考情報) |
judge6 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 17 |
ソースコード
// 解法:各点 (i, P_i) の層 = 「i で終わる最長増加部分列の長さ」 // パーシェンスソーティングで各 i の LIS 長 L_i を O(log N) で求める。 // 各層 k について、x の最小値 = 最小の i, y の最小値 = 最小の P_i を集計して出力。 #include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N; if (!(cin >> N)) return 0; vector<int> P(N); for (int i = 0; i < N; ++i) cin >> P[i]; vector<int> tails; // tails[len-1] = 長さ len の増加列の最小 possible 終端値 vector<int> L(N); // 各 i の LIS 長(厳密増加) tails.reserve(N); for (int i = 0; i < N; ++i) { int a = P[i]; // 厳密増加 LIS: lower_bound (>= a) の位置に置く int pos = int(lower_bound(tails.begin(), tails.end(), a) - tails.begin()); if (pos == (int)tails.size()) tails.push_back(a); else tails[pos] = a; L[i] = pos + 1; // 層番号 = LIS 長 } int K = (int)tails.size(); // 総ラウンド数 = 総層数 const int INF = 1e9; vector<int> minX(K + 1, INF), minY(K + 1, INF); // 1-indexed 層 for (int i = 0; i < N; ++i) { int k = L[i]; minX[k] = min(minX[k], i + 1); // x = index i+1 minY[k] = min(minY[k], P[i]); // y = P_i } for (int k = 1; k <= K; ++k) { cout << minX[k] << ' ' << minY[k] << '\n'; } return 0; }