题目链接:点击打开链接
给定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 */