#include <bits/stdc++.h>
using namespace std;
/*
JOI mart – Impression Score
O(N log N) 풀이
아이디어 요약:
- 인덱스 x를 A[x] 오름차순(같은 값은 x 내림차순)으로 처리.
- processed = 이미 처리한 인덱스들의 집합 (경계용으로 0, n+1 포함)
- barrier = "왼쪽 경계 후보" 집합. 초기엔 [1..n-D]를 모두 담고 시작.
어떤 인덱스 x를 처리할 때, x의 processed 이웃 (prel, prer)을 보고
prer - prel > D라면, x를 경계로 좌/우 D안에 있는 구간의 barrier를 지운다.
그 뒤 x의 왼쪽 경계 left = (barrier.lower_bound(x)의 직전 원소) 또는 1.
- dp[x] = 1 + max(dp[left..x-1]) (세그트리로 range max)
- 정답 = max(dp[1..n]) (마지막 날 포함 조건은 중간 삽입으로 항상 충족 가능)
*/
struct SegTree {
int n;
vector<int> st;
SegTree(int N=0): n(N), st(4*N+5, 0) {}
void update(int node, int l, int r, int pos, int val){
if(l==r){ st[node]=val; return; }
int m=(l+r)>>1;
if(pos<=m) update(node<<1, l, m, pos, val);
else update(node<<1|1, m+1, r, pos, val);
st[node] = max(st[node<<1], st[node<<1|1]);
}
void update(int pos, int val){ update(1,1,n,pos,val); }
int query(int node, int l, int r, int ql, int qr){
if(qr<l || r<ql) return 0;
if(ql<=l && r<=qr) return st[node];
int m=(l+r)>>1;
return max(query(node<<1,l,m,ql,qr), query(node<<1|1,m+1,r,ql,qr));
}
int query(int l, int r){ if(l>r) return 0; return query(1,1,n,l,r); }
};
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, D;
cin >> n >> D;
vector<long long> A(n+1);
for(int i=1;i<=n;i++) cin >> A[i];
// 값 기준 정렬: (값 오름차순, 인덱스 내림차순)
vector<int> perm(n);
iota(perm.begin(), perm.end(), 1);
sort(perm.begin(), perm.end(), [&](int x, int y){
if (A[x] != A[y]) return A[x] < A[y];
return x > y;
});
SegTree st(n);
vector<int> dp(n+1, 0);
// processed: 이미 처리된 인덱스(경계 포함)
set<int> processed;
processed.insert(0);
processed.insert(n+1);
// barrier: 왼쪽 경계 후보들
set<int> barrier;
for(int i=1;i<=n-D;i++) barrier.insert(i);
for(int x : perm){
// processed 이웃 찾기
auto it = processed.lower_bound(x);
int prer = *it;
int prel = *prev(it);
// 큰 공백을 x가 메울 때, x와 양쪽 경계 사이가 D 이내면 해당 구간의 barrier 제거
if (prer - prel > D) {
if (prer - x <= D) {
// 지울 구간: [x .. prer-1]이지만, barrier엔 최대 n-D까지만 존재
int L = x, R = min(prer-1, n-D);
if (L <= R) {
auto itL = barrier.lower_bound(L);
while (itL != barrier.end() && *itL <= R) itL = barrier.erase(itL);
}
}
if (x - prel <= D) {
int L = max(prel, 1), R = min(x, n-D);
if (L <= R) {
auto itL = barrier.lower_bound(L);
while (itL != barrier.end() && *itL <= R) itL = barrier.erase(itL);
}
}
}
processed.insert(x);
// x에 대한 왼쪽 경계 left 구하기
auto itb = barrier.lower_bound(x);
int left = (itb == barrier.begin() ? 1 : *prev(itb));
// dp[x] = 1 + max(dp[left..x-1])
dp[x] = st.query(left, x-1) + 1;
st.update(x, dp[x]);
}
// 전체 최댓값 = 정답 (마지막 날 포함 조건은 중간 삽입으로 항상 만족시키며 점수는 감소하지 않음)
cout << st.query(1, n) << '\n';
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgovKgogIEpPSSBtYXJ0IOKAkyBJbXByZXNzaW9uIFNjb3JlCiAgTyhOIGxvZyBOKSDtkoDsnbQKICDslYTsnbTrlJTslrQg7JqU7JW9OgogIC0g7J24642x7IqkIHjrpbwgQVt4XSDsmKTrpoTssKjsiJwo6rCZ7J2AIOqwkuydgCB4IOuCtOumvOywqOyInCnsnLzroZwg7LKY66asLgogIC0gcHJvY2Vzc2VkID0g7J2066+4IOyymOumrO2VnCDsnbjrjbHsiqTrk6TsnZgg7KeR7ZWpICjqsr3qs4TsmqnsnLzroZwgMCwgbisxIO2PrO2VqCkKICAtIGJhcnJpZXIgPSAi7Jm87Kq9IOqyveqzhCDtm4Trs7QiIOynke2VqS4g7LSI6riw7JeUIFsxLi5uLURd66W8IOuqqOuRkCDri7Tqs6Ag7Iuc7J6RLgogICAg7Ja065akIOyduOuNseyKpCB466W8IOyymOumrO2VoCDrlYwsIHjsnZggcHJvY2Vzc2VkIOydtOybgyAocHJlbCwgcHJlcinsnYQg67O06rOgCiAgICBwcmVyIC0gcHJlbCA+IETrnbzrqbQsIHjrpbwg6rK96rOE66GcIOyijC/smrAgROyViOyXkCDsnojripQg6rWs6rCE7J2YIGJhcnJpZXLrpbwg7KeA7Jq064ukLgogICAg6re4IOuSpCB47J2YIOyZvOyqvSDqsr3qs4QgbGVmdCA9IChiYXJyaWVyLmxvd2VyX2JvdW5kKHgp7J2YIOyngeyghCDsm5DshowpIOuYkOuKlCAxLgogIC0gZHBbeF0gPSAxICsgbWF4KGRwW2xlZnQuLngtMV0pICAo7IS46re47Yq466as66GcIHJhbmdlIG1heCkKICAtIOygleuLtSA9IG1heChkcFsxLi5uXSkgICjrp4jsp4Drp4kg64KgIO2PrO2VqCDsobDqsbTsnYAg7KSR6rCEIOyCveyeheycvOuhnCDtla3sg4Eg7Lap7KGxIOqwgOuKpSkKKi8KCnN0cnVjdCBTZWdUcmVlIHsKICAgIGludCBuOwogICAgdmVjdG9yPGludD4gc3Q7CiAgICBTZWdUcmVlKGludCBOPTApOiBuKE4pLCBzdCg0Kk4rNSwgMCkge30KICAgIHZvaWQgdXBkYXRlKGludCBub2RlLCBpbnQgbCwgaW50IHIsIGludCBwb3MsIGludCB2YWwpewogICAgICAgIGlmKGw9PXIpeyBzdFtub2RlXT12YWw7IHJldHVybjsgfQogICAgICAgIGludCBtPShsK3IpPj4xOwogICAgICAgIGlmKHBvczw9bSkgdXBkYXRlKG5vZGU8PDEsIGwsIG0sIHBvcywgdmFsKTsKICAgICAgICBlbHNlICAgICAgIHVwZGF0ZShub2RlPDwxfDEsIG0rMSwgciwgcG9zLCB2YWwpOwogICAgICAgIHN0W25vZGVdID0gbWF4KHN0W25vZGU8PDFdLCBzdFtub2RlPDwxfDFdKTsKICAgIH0KICAgIHZvaWQgdXBkYXRlKGludCBwb3MsIGludCB2YWwpeyB1cGRhdGUoMSwxLG4scG9zLHZhbCk7IH0KICAgIGludCBxdWVyeShpbnQgbm9kZSwgaW50IGwsIGludCByLCBpbnQgcWwsIGludCBxcil7CiAgICAgICAgaWYocXI8bCB8fCByPHFsKSByZXR1cm4gMDsKICAgICAgICBpZihxbDw9bCAmJiByPD1xcikgcmV0dXJuIHN0W25vZGVdOwogICAgICAgIGludCBtPShsK3IpPj4xOwogICAgICAgIHJldHVybiBtYXgocXVlcnkobm9kZTw8MSxsLG0scWwscXIpLCBxdWVyeShub2RlPDwxfDEsbSsxLHIscWwscXIpKTsKICAgIH0KICAgIGludCBxdWVyeShpbnQgbCwgaW50IHIpeyBpZihsPnIpIHJldHVybiAwOyByZXR1cm4gcXVlcnkoMSwxLG4sbCxyKTsgfQp9OwoKaW50IG1haW4oKXsKICAgIGlvczo6c3luY193aXRoX3N0ZGlvKGZhbHNlKTsKICAgIGNpbi50aWUobnVsbHB0cik7CgogICAgaW50IG4sIEQ7CiAgICBjaW4gPj4gbiA+PiBEOwogICAgdmVjdG9yPGxvbmcgbG9uZz4gQShuKzEpOwogICAgZm9yKGludCBpPTE7aTw9bjtpKyspIGNpbiA+PiBBW2ldOwoKICAgIC8vIOqwkiDquLDspIAg7KCV66CsOiAo6rCSIOyYpOumhOywqOyInCwg7J24642x7IqkIOuCtOumvOywqOyInCkKICAgIHZlY3RvcjxpbnQ+IHBlcm0obik7CiAgICBpb3RhKHBlcm0uYmVnaW4oKSwgcGVybS5lbmQoKSwgMSk7CiAgICBzb3J0KHBlcm0uYmVnaW4oKSwgcGVybS5lbmQoKSwgWyZdKGludCB4LCBpbnQgeSl7CiAgICAgICAgaWYgKEFbeF0gIT0gQVt5XSkgcmV0dXJuIEFbeF0gPCBBW3ldOwogICAgICAgIHJldHVybiB4ID4geTsKICAgIH0pOwoKICAgIFNlZ1RyZWUgc3Qobik7CiAgICB2ZWN0b3I8aW50PiBkcChuKzEsIDApOwoKICAgIC8vIHByb2Nlc3NlZDog7J2066+4IOyymOumrOuQnCDsnbjrjbHsiqQo6rK96rOEIO2PrO2VqCkKICAgIHNldDxpbnQ+IHByb2Nlc3NlZDsKICAgIHByb2Nlc3NlZC5pbnNlcnQoMCk7CiAgICBwcm9jZXNzZWQuaW5zZXJ0KG4rMSk7CgogICAgLy8gYmFycmllcjog7Jm87Kq9IOqyveqzhCDtm4Trs7Trk6QKICAgIHNldDxpbnQ+IGJhcnJpZXI7CiAgICBmb3IoaW50IGk9MTtpPD1uLUQ7aSsrKSBiYXJyaWVyLmluc2VydChpKTsKCiAgICBmb3IoaW50IHggOiBwZXJtKXsKICAgICAgICAvLyBwcm9jZXNzZWQg7J207JuDIOywvuq4sAogICAgICAgIGF1dG8gaXQgPSBwcm9jZXNzZWQubG93ZXJfYm91bmQoeCk7CiAgICAgICAgaW50IHByZXIgPSAqaXQ7CiAgICAgICAgaW50IHByZWwgPSAqcHJldihpdCk7CgogICAgICAgIC8vIO2BsCDqs7XrsLHsnYQgeOqwgCDrqZTsmrgg65WMLCB47JmAIOyWkeyqvSDqsr3qs4Qg7IKs7J206rCAIEQg7J2064K066m0IO2VtOuLuSDqtazqsITsnZggYmFycmllciDsoJzqsbAKICAgICAgICBpZiAocHJlciAtIHByZWwgPiBEKSB7CiAgICAgICAgICAgIGlmIChwcmVyIC0geCA8PSBEKSB7CiAgICAgICAgICAgICAgICAvLyDsp4Dsmrgg6rWs6rCEOiBbeCAuLiBwcmVyLTFd7J207KeA66eMLCBiYXJyaWVy7JeUIOy1nOuMgCBuLUTquYzsp4Drp4wg7KG07J6sCiAgICAgICAgICAgICAgICBpbnQgTCA9IHgsIFIgPSBtaW4ocHJlci0xLCBuLUQpOwogICAgICAgICAgICAgICAgaWYgKEwgPD0gUikgewogICAgICAgICAgICAgICAgICAgIGF1dG8gaXRMID0gYmFycmllci5sb3dlcl9ib3VuZChMKTsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaXRMICE9IGJhcnJpZXIuZW5kKCkgJiYgKml0TCA8PSBSKSBpdEwgPSBiYXJyaWVyLmVyYXNlKGl0TCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHggLSBwcmVsIDw9IEQpIHsKICAgICAgICAgICAgICAgIGludCBMID0gbWF4KHByZWwsIDEpLCBSID0gbWluKHgsIG4tRCk7CiAgICAgICAgICAgICAgICBpZiAoTCA8PSBSKSB7CiAgICAgICAgICAgICAgICAgICAgYXV0byBpdEwgPSBiYXJyaWVyLmxvd2VyX2JvdW5kKEwpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChpdEwgIT0gYmFycmllci5lbmQoKSAmJiAqaXRMIDw9IFIpIGl0TCA9IGJhcnJpZXIuZXJhc2UoaXRMKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJvY2Vzc2VkLmluc2VydCh4KTsKCiAgICAgICAgLy8geOyXkCDrjIDtlZwg7Jm87Kq9IOqyveqzhCBsZWZ0IOq1rO2VmOq4sAogICAgICAgIGF1dG8gaXRiID0gYmFycmllci5sb3dlcl9ib3VuZCh4KTsKICAgICAgICBpbnQgbGVmdCA9IChpdGIgPT0gYmFycmllci5iZWdpbigpID8gMSA6ICpwcmV2KGl0YikpOwoKICAgICAgICAvLyBkcFt4XSA9IDEgKyBtYXgoZHBbbGVmdC4ueC0xXSkKICAgICAgICBkcFt4XSA9IHN0LnF1ZXJ5KGxlZnQsIHgtMSkgKyAxOwogICAgICAgIHN0LnVwZGF0ZSh4LCBkcFt4XSk7CiAgICB9CgogICAgLy8g7KCE7LK0IOy1nOuMk+qwkiA9IOygleuLtSAo66eI7KeA66eJIOuCoCDtj6ztlagg7KGw6rG07J2AIOykkeqwhCDsgr3snoXsnLzroZwg7ZWt7IOBIOunjOyhseyLnO2CpOupsCDsoJDsiJjripQg6rCQ7IaM7ZWY7KeAIOyViuydjCkKICAgIGNvdXQgPDwgc3QucXVlcnkoMSwgbikgPDwgJ1xuJzsKICAgIHJldHVybiAwOwp9