题目链接:点击打开链接
给定n d
下面n座山的高度。
任选一座山,每次可以跳到右边的任意距离的山,问最多能经过几座山,并输出路径。
且→跳时,两座山的高度差必须>=d
思路:
线段树维护高度为x的山的值和前驱。
高度离散一下。
然后这么搞搞。。
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <map>
#include <vector>
typedef long long ll;
template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
ret*=sgn;
return 1;
}
template <class T>
inline void pt(T x) {
if (x <0) {
putchar('-');
x = -x;
}
if(x>9) pt(x/10);
putchar(x%10+'0');
}
const int N = 300010;
using namespace std;
typedef pair<int,int> pii;
#define L(x) tree[x].l
#define R(x) tree[x].r
#define Lson(x) (x<<1)
#define Rson(x) (x<<1|1)
#define P(x) tree[x].p
struct node{
int l, r;
pii p;
}tree[N<<2];
map<ll, int> mp;
vector<ll>G;
void push_up(int id){
P(id) = max(P(Lson(id)), P(Rson(id)));
}
void build(int l, int r, int id){
L(id) = l; R(id) = r;
P(id) = pii(0, -1);
if(l == r)
return ;
int mid = (l+r)>>1;
build(l, mid, Lson(id)); build(mid+1, r, Rson(id));
}
pii query(int l, int r, int id){
if( l == L(id) && R(id) == r)
return P(id);
int mid = (L(id) + R(id))>>1;
if(mid < l)
return query(l, r, Rson(id));
else if(r <= mid)
return query(l, r, Lson(id));
else
return max(query(l, mid, Lson(id)), query(mid+1, r, Rson(id)) );
}
void updata(int pos, pii p, int id){
if(L(id) == R(id))
{
P(id) = max(P(id), p);
return ;
}
int mid = (L(id) + R(id))>>1;
if(mid < pos)
updata(pos, p, Rson(id));
else if(pos <= mid)
updata(pos, p, Lson(id));
push_up(id);
}
ll a[N], d;
int n, dp[N];
void input(){
mp.clear(); G.clear();
for(int i = 1; i <= n; i++) {
rd(a[i]);
G.push_back(a[i]);
G.push_back(a[i]+d);
G.push_back(a[i]-d);
}
sort(G.begin(), G.end());
G.erase(unique(G.begin(), G.end()), G.end());
for(int i = 0; i < G.size(); i++) mp[G[i]] = i+1;
}
vector<int>hehe;
int main(){
pii ans;
while(cin>>n>>d){
input();
build(1, (int)G.size(), 1);
for(int i = 1; i <= n; i++)
{
ans = max( query(1, mp[a[i]-d], 1), query(mp[a[i]+d], (int)G.size(), 1));
dp[i] = ans.second;
ans.first++; ans.second = i;
updata(mp[a[i]], ans, 1);
}
ans = query(1, (int)G.size(), 1);
int u = ans.second;
hehe.clear();
while(~u)
hehe.push_back(u), u = dp[u];
pt(hehe.size()); putchar('\n');
for(int i = hehe.size()-1; i >= 0; i--)
printf("%d%c", hehe[i], i==0?'\n':' ');
}
return 0;
}
/*
6 3
4 1 3 0 3 0
*/