link
- 水题 很容易写出 dp方程 dp[i]=max(dp[j])+1
- 我们需要做的就是如何找到这个j 因为有条件 abs(a[i]- a[j])>=d
- 显然 我们把它拆开后线段树维护
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
#define fi first
#define se second
#define pb push_back
#define inf 1ll<<62
#define db double
#define endl "\n"
#define min(a,b) ((a)<(b)?(a):(b))
#define de_bug(x) cerr << #x << "=" << x << endl
#define all(a) a.begin(),a.end()
#define IOS std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fer(i,a,b) for(int i=a;i<=b;i++)
#define der(i,a,b) for(int i=a;i>=b;i--)
const int mod = 1e9 + 7;
const int N = 1e6 + 10;
int n, m , k;
int a[N];
int b[N];
int pre[N];
int cnt;
int dp[N];
struct node {
int l, r;
int pos, ans;
#define ls i*2
#define rs i*2+1
} tr[N << 2];
void build(int i, int l, int r) {
tr[i] = {l, r};
if(l == r)return ;
int mid = l + r >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
}
void change(int i, int x, int id) {
if(tr[i].l == tr[i].r) {
if(dp[id] > tr[i].ans) tr[i].ans = dp[id], tr[i].pos = id;
return ;
}
int mid = tr[i].l + tr[i].r >> 1;
if(x <= mid) change(ls, x, id);
else change(rs, x, id);
if(tr[ls].ans > tr[rs].ans) tr[i].ans = tr[ls].ans, tr[i].pos = tr[ls].pos;
else tr[i].ans = tr[rs].ans, tr[i].pos = tr[rs].pos;
}
pii query(int i, int l, int r) {
if(l <= tr[i].l && tr[i].r <= r) {
return make_pair(tr[i].ans, tr[i].pos);
}
int mid = tr[i].l + tr[i].r >> 1;
pii ans;
if(l <= mid) ans = max(ans, query(ls, l, r));
if(r > mid) ans = max(ans, query(rs, l, r));
return ans;
}
int tot;
int get(int x) {
return lower_bound(b + 1, b + tot + 1, x) - b;
}
void dfs(int x) {
if(!pre[x]) {
cout << x << " ";
return ;
}
dfs(pre[x]);
cout << x << " ";
}
void solve() {
cin >> n >> m;
int cnt = 0;
fer(i, 1, n) {
cin >> a[i];
b[++cnt] = a[i];
b[++cnt] = max(a[i] - m, 0ll);
b[++cnt] = a[i] + m;
}
sort(b + 1, b + cnt + 1);
tot = unique(b + 1, b + cnt + 1) - (b + 1);
int ans = 0;
build(1, 1, tot);
fer(i, 1, n) {
pii x = query(1, 0, max(get(a[i] - m), 0ll));
pii y = query(1, get(a[i] + m), tot);
if(x.first > y.first) {
dp[i] = x.fi + 1;
pre[i] = x.se;
} else {
dp[i] = y.fi + 1;
pre[i] = y.se;
}
ans = max(ans, dp[i]);
change(1, get(a[i]), i);
}
cout << ans << endl;
int tmp;
fer(i, 1, n) {
if(dp[i] == ans) {
tmp = i;
}
}
dfs(tmp);
cout << endl;
}
signed main() {
IOS;
int _ = 1;
while( _-- )
solve();
return 0;
}