-
Notifications
You must be signed in to change notification settings - Fork 7
/
implicit_segment_tree_general.cc
115 lines (103 loc) · 2.88 KB
/
implicit_segment_tree_general.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Problem : https://codeforces.com/contest/474/problem/E
// use : Generalized implicit segtree (can store multiple info inside node)
/*
Author: Nachiket Kanore
Created: Thursday 31 December 2020 06:53:21 PM IST
(ツ) A goal is a dream with a deadline.
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cassert>
#include <string>
#include <cstring>
#define int long long
#define pb push_back
#define ALL(x) (x).begin(),(x).end()
#define sz(x) (int)(x.size())
#define FOR(i,L,R) for(int i = (L); i <= (R); i++)
using namespace std;
template<class T> bool cmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; }
template<class T> bool cmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }
const int INF = 1e15;
const int N = 1e5 + 5;
int n, d;
int next_id[N];
int h[N];
class implicit_segtree {
public:
struct node{
pair < int , int > val;
node* left;
node* right;
node(pair < int , int > _val = make_pair(0 , n + 1) , node* _left = NULL , node* _right = NULL){
val = _val;
left = _left;
right = _right;
}
};
typedef node* pnode;
pair < int , int > val(pnode tree){
if(tree){
return tree -> val;
}
return make_pair(0 , n + 1);
}
void update(long long l , long long r , pnode &tree , long long idx , int value , int pos){
if(!tree){
tree = new node();
}
if(l == r){
tree -> val = max(tree -> val , make_pair(value , pos));
return;
}
long long mid = (l + r) >> 1;
if(idx <= mid){
update(l , mid , tree -> left , idx , value , pos);
}
else{
update(mid + 1 , r , tree -> right , idx , value , pos);
}
tree -> val = max(val(tree -> left) , val(tree -> right));
}
pair < int , int > query(long long l , long long r , pnode tree , long long ql , long long qr){
if(!tree || l > qr || r < ql || ql > qr){
return make_pair(0 , n + 1);
}
if(l >= ql && r <= qr){
return val(tree);
}
long long mid = (l + r) >> 1;
return max(query(l , mid , tree -> left , ql , qr) , query(mid + 1 , r , tree -> right , ql , qr));
}
pnode root = NULL;
} T;
int32_t main() {
ios::sync_with_stdio(0); cin.tie(0);
cin >> n;
cin >> d;
for (int i = 1; i <= n; i++) {
cin >> h[i];
next_id[i] = INF;
}
for (int L = n; L >= 1; L--) {
pair<int,int> best_ans_ahead = max(T.query(1, INF, T.root, h[L] + d, INF), T.query(1, INF, T.root, 1, h[L] - d));
int ans_here = best_ans_ahead.first + 1;
int idx = best_ans_ahead.second;
next_id[L] = idx;
T.update(1, INF, T.root, h[L], ans_here, L);
}
pair<int,int> best_ans = T.val(T.root);
int best_len = best_ans.first;
int start = best_ans.second;
assert(best_len > 0);
cout << best_len << '\n';
assert(start >= 1 && start <= n);
while (start <= n) {
cout << start << ' ';
start = next_id[start];
}
}