DOJ logoDOJ
問題
最近追加された問題保存した問題
カテゴリDLCコンテストグループチーム掲示板
ランキング
正解数ランキングストリークランキングDOJ Powerランキング
提出状況
問題募集ログイン新規登録
DOJ logoDOJ

OI形式のサブタスク採点、Eloレーティング、Discord認証を備えたオンラインジャッジです。

問題
問題一覧カテゴリ
コミュニティ
コンテストランキング掲示板お知らせ外部のコンテストを開催するガイド
アカウント
ログイン新規登録ジャッジ状態
ポリシー
利用規約DLCの利用規則プライバシーAPI 文書言語ランタイムコンテストの順位報酬レーティングとパフォーマンス
© 2026 DOJ
All rights reserved
解説

Fat Sequence

問題に戻る

解説

AiA_iAi​에서 끝나는 가장 긴 증가하는 부분수열의 길이를 AiA_iAi​의 레벨 LiL_iLi​라 하고, K=max⁡LiK = \max L_iK=maxLi​라 하자. 모든 LiL_iLi​는 잘 알려진 lower\_bound 방식의 LIS 알고리즘으로 O(Nlog⁡N)O(N \log N)O(NlogN)에 구할 수 있다.

관찰 1. 길이 KKK인 증가하는 부분수열의 kkk번째 원소는 레벨이 정확히 kkk이다. 앞의 kkk개 원소가 증가하는 부분수열을 이루므로 레벨은 kkk 이상이다. 레벨이 kkk보다 크다면 그 뒤의 개 원소를 이어 붙여 길이가 보다 긴 증가하는 부분수열을 만들 수 있으므로 모순이다.

관찰 2. 레벨이 같은 원소들을 인덱스 순으로 나열하면 값이 감소하지 않는다. j<ij < ij<i, Lj=LiL_j = L_iLj​=Li​인데 라면 를 뒤에 붙일 수 있으므로 이 되어 모순이다.

관찰 3. 위 레벨부터 가장 큰 값을 고르면 된다. 다음과 같이 gK,gK−1,⋯ ,g1g_K, g_{K-1}, \cdots, g_1gK​,gK−1​,⋯,g을 정한다.

  • gKg_KgK​는 레벨 KKK인 원소 중 가장 앞에 있는 것, 즉 값이 가장 큰 것이다.
  • gkg_kgk​ (k<K)는 레벨 인 원소 중 값이 보다 작은 것들 가운데 가장 앞에 있는 것이다. 관찰 2에 의해 이것은 그중 값이 가장 큰 원소이다.

gk+1g_{k+1}gk+1​의 레벨이 k+1k+1k+1이므로, gk+1g_{k+1}g보다 앞에 있으면서 값이 더 작은 레벨 원소가 존재한다. 는 그런 원소들 중 가장 앞에 있으므로 인덱스도 자동으로 보다 앞이다. 따라서 는 길이 인 증가하는 부분수열이다.

이제 임의의 길이 KKK인 증가하는 부분수열 h1,h2,⋯ ,hKh_1, h_2, \cdots, h_Kh1​,h2​,⋯,h를 생각하자. 관찰 1에 의해 의 레벨은 이다. 부터 내려가며 임을 보인다. 는 의 정의에서 바로 나온다. 이라면 이고, 는 레벨 이면서 보다 작은 값 중 최댓값이므로 이다.

따라서 모든 kkk에 대해 hk≤gkh_k \leq g_khk​≤gk​이고, ggg가 뚱뚱한 수열이다. 합이 같다면 모든 원소가 같아야 하므로 뚱뚱한 수열의 원소 값은 항상 유일하다.

구현. 원소들을 레벨별로 인덱스 순서를 유지하며 모은다. 각 레벨의 목록을 앞에서부터 훑으며 값이 gk+1g_{k+1}gk+1​보다 작은 첫 원소를 찾으면 되고, 각 목록을 한 번씩만 훑으므로 이 부분은 O(N)O(N)O(N)이다.

int bound = INT_MAX;
for (int k = K - 1; k >= 0; k--) {
    int p = st[k];
    while (a[ord[p]] >= bound) p++;
    pick[k] = a[ord[p]];
    bound = pick[k];
}

전체 시간복잡도는 O(Nlog⁡N)O(N \log N)O(NlogN)이다. 합은 최대 약 101510^{15}1015이므로 64비트 정수를 써야 한다.

뒤에서부터 훑으며 처음 만나는 원소를 고르는 일반적인 LIS 역추적은 각 레벨에서 가능한 가장 작은 값을 고르므로 틀린다. 증가가 강증가라는 점에도 주의해야 한다. lower\_bound 대신 upper\_bound를 쓰면 같은 값이 있는 입력에서 틀린다.

서브태스크별 풀이.

  • 서브태스크 1: 모든 부분수열을 확인한다. O(2NN)O(2^N N)O(2NN).
  • 서브태스크 2: (길이,합)(\text{길이}, \text{합})(길이,합)의 사전순 최댓값을 상태로 두는 O(N2)O(N^2)O(N DP와 역추적.

Solution written by ClaudeOpus5.5

K−kK-k
K−k
KKK
Aj<AiA_j < A_i
Aj​<Ai​
AiA_iAi​
AjA_jAj​
Li≥Lj+1L_i \geq L_j + 1Li​≥Lj​+1
1
​
k < K
k<K
kkk
gk+1g_{k+1}gk+1​
k+1
​
kkk
gkg_kgk​
gk+1g_{k+1}gk+1​
g1,g2,⋯ ,gKg_1, g_2, \cdots, g_Kg1​,g2​,⋯,gK​
KKK
K
​
hkh_khk​
kkk
k=Kk = Kk=K
hk≤gkh_k \leq g_khk​≤gk​
hK≤gKh_K \leq g_KhK​≤gK​
gKg_KgK​
hk+1≤gk+1h_{k+1} \leq g_{k+1}hk+1​≤gk+1​
hk<hk+1≤gk+1h_k < h_{k+1} \leq g_{k+1}hk​<hk+1​≤gk+1​
gkg_kgk​
kkk
gk+1g_{k+1}gk+1​
hk≤gkh_k \leq g_khk​≤gk​
2
)
  • 서브태스크 3: 같은 DP를 값마다 하나씩 관리한다. 값이 xxx인 원소는 값이 xxx보다 작은 상태들만 보면 되므로 O(100N)O(100N)O(100N)이다.
  • 서브태스크 4: 위의 풀이. 좌표 압축 후 펜윅 트리로 (길이,합)(\text{길이}, \text{합})(길이,합)의 사전순 최댓값을 관리해도 O(Nlog⁡N)O(N \log N)O(NlogN)에 해결된다.