给出n个数字,和最小间隔d。从i能走到j的充要条件就是 |ai−aj|≥d ,求最长的路径长度并输出路径,有多解输出任意一组路径。
思路就是dp[i]表示以i结尾的最长路径长度,dp[i]<-{pre{dp[j]}里面满足条件且最长的长度} + 1,
这里查找的就可以是区间最大值的查找,因为要记录路径,所以里面还需要最大值对应的原序列中的位置。
const int maxn = 1e5 + 123;
struct data {
int len, loc;
data() {}
data(int len,int loc) : len(len), loc(loc) {}
data operator + (const data& rhs) {
return len >= rhs.len ? *this : rhs;
}
};
struct node {
int l, r;
data v;
}p[maxn<<4];
void build(int rt, int l, int r) {
p[rt] = node {l, r, data(0, 0)};
if (l == r) return ;
int mid = (l + r) >> 1;
build(lson, l, mid);
build(rson, mid + 1, r);
}
inline void push_up(int rt) {
p[rt].v = p[lson].v + p[rson].v;
}
void updata(int rt,int pos, data v) {
if (p[rt].l == pos && p[rt].r == pos) {
p[rt].v = p[rt].v + v;
return ;
}
int mid = (p[rt].l + p[rt].r) >> 1;
if (pos <= mid) updata(lson, pos, v);
if (pos > mid) updata(rson, pos, v);
push_up(rt);
}
data find(int rt,int L, int R) {
if (L <= p[rt].l && p[rt].r <= R) return p[rt].v;
int mid = (p[rt].l + p[rt].r) >> 1;
if (R <= mid) return find(lson, L, R);
if (L > mid) return find(rson, L, R);
return find(lson, L, R) + find(rson, L, R);
}
LL h[maxn*5], a[maxn];
int m;
int nxt[maxn];
int n, d;
int main(int argc, const char * argv[])
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
// ios::sync_with_stdio(false);
// cout.sync_with_stdio(false);
// cin.sync_with_stdio(false);
cin >> n >> d;
Rep(i, 1, n) {
scanf("%lld", &a[i]);
h[++m] = a[i];
h[++m] = max(0LL, a[i] - d);
h[++m] = a[i] + d;
}
sort(h + 1, h + 1 + m);
m = unique(h + 1, h + 1 + m) - h - 1;
build(1, 1, m);
int res = 0;
int o = 1;
Rep(i, 1, n) {
int l = lower_bound(h + 1, h + 1 + m, max(0LL, a[i] - d)) - h;
int r = lower_bound(h + 1, h + 1 + m, a[i] + d) - h;
data v = find(1, 1, l) + find(1, r, m);
nxt[i] = v.loc;
if (v.len + 1 > res) {
res = v.len + 1;
o = i;
}
int pos = lower_bound(h + 1, h + 1 + m, a[i]) - h;
updata(1, pos, data(v.len + 1, i));
}
vector<int> vec;
printf("%d\n", res);
for (int u = o;u ; u = nxt[u])
vec.push_back(u);
for (int i = res - 1;i >= 0;--i)
printf("%d ", vec[i]);
puts("");
// showtime;
return 0;
}