結果
| 問題 |
No.3238 Shadow
|
| コンテスト | |
| ユーザー |
Moss_Local
|
| 提出日時 | 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;
}
Moss_Local