- 柱子(Pillars)
线段树模板以及离散化
- @ 2026-8-7 11:35:30
/*
单点修改 区间合并 线段树 区间 1 - n
注意 change里面的单点修改的逻辑要注意,是+还是覆盖
*/
template <class Info>
struct Segtree{
int n;
vector<Info> info;
Segtree(int n_, Info info = Info()) {
init(vector<Info>(n_ + 1, info));
}
Segtree() : n(0) {}
void init(const vector<Info> &init) {
n = (int)init.size() - 1;
info.assign(4 * n + 2, Info{});
build(1, 1, n, init);
}
void build(int u, int l, int r, const vector<Info> &init) {
if(l == r) {
info[u] = init[l];
return;
}
int mid = l + r >> 1;
build(u * 2, l, mid, init); build(u * 2 + 1, mid + 1, r, init);
info[u] = info[u * 2] + info[u * 2 + 1];
}
void change(int u, int p, const Info & x, int ul, int ur) {
if(ul == ur) {
info[u] = info[u] + x; // todo
return;
}
int mid = ul + ur >> 1;
if(p <= mid) change(u * 2, p, x, ul, mid);
else change(u * 2 + 1, p, x, mid + 1, ur);
info[u] = info[u * 2] + info[u * 2 + 1];
}
void change(int p, const Info & x) {
change(1, p, x, 1, n);
}
Info query(int u, int l, int r, int ul, int ur) {
if(l <= ul && r >= ur) {
return info[u];
}
int mid = ul + ur >> 1;
if(r <= mid) return query(u * 2, l, r, ul, mid);
if(l > mid) return query(u * 2 + 1, l, r, mid + 1, ur);
return query(u * 2, l, r, ul, mid) + query(u * 2 + 1, l, r, mid + 1, ur);
}
Info query(int l, int r) {
return query(1, l, r, 1, n);
}
};
struct Info {
int mx, i;
Info operator+ (const Info &t) const {
if (mx >= t.mx) return *this;
return t;
}
};
void solve() {
ll n, d;
cin >> n >> d;
vector<ll> a(n + 1);
const ll inf = 1e18;
vector<ll> A = {-inf, -inf + 1};
for (int i = 1; i <= n; i++) {
cin >> a[i];
A.push_back({a[i]});
A.push_back({a[i] - d});
A.push_back({a[i] + d});
}
sort(A.begin(), A.end()); A.erase(unique(A.begin(), A.end()), A.end());
int N = (int)A.size() - 1;
Segtree<Info> t(N);
vector<int> pre(n + 1), dp(n + 1);
for (int i = 1; i <= n; i++) {
int r = lower_bound(A.begin(), A.end(), a[i] - d) - A.begin();
auto info1 = t.query(1, r);
int l = lower_bound(A.begin(), A.end(), a[i] + d) - A.begin();
auto info2 = t.query(l, N);
auto info = info1 + info2;
dp[i] = info.mx + 1, pre[i] = info.i;
t.change(lower_bound(A.begin(), A.end(), a[i]) - A.begin(), {dp[i], i});
}
auto info = t.query(1, N);
int x = info.i;
vector<int> ans;
while (x) {
ans.push_back(x);
x = pre[x];
}
reverse(ans.begin(), ans.end());
cout << ans.size() << '\n';
for (auto x : ans) cout << x << ' '; cout << '\n';
}
0 条评论
目前还没有评论...
信息
- ID
- 571
- 时间
- ms
- 内存
- MiB
- 难度
- 5
- 标签
- 递交数
- 23
- 已通过
- 2
- 上传者