/*
单点修改 区间合并 线段树 区间 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
上传者