CodeForces 474E Pillars (maximum interval between line breaks)

Topic link

Given n numbers, and the minimum interval d. The necessary and sufficient condition for walking from i to j is |aiaj|d , Find the longest path length and output the path, there are multiple solutions to output any set of paths.
The idea is that dp[i] represents the longest path length ending with i, dp[i]<-{pre{dp[j]} which satisfies the condition and the longest length} + 1, the
search here can be the largest interval For the value search, because the path needs to be recorded, the position in the original sequence corresponding to the maximum value is also needed.

const int maxn = 1e5 + 123;
struct data {
    int len, loc;
    data() {}
    data(int len,int loc) : len(len), loc(loc) {}
    data operator + (const data& rhs) {
        return len >= rhs.len ? *this : rhs;
    }
};
struct node {
    int l, r;
    data v;
}p[maxn<<4];
void build(int rt, int l, int r) {
    p[rt] = node {l, r, data(0, 0)};
    if (l == r) return ;
    int mid = (l + r) >> 1;
    build(lson, l, mid);
    build(rson, mid + 1, r);
}
inline void push_up(int rt) {
    p[rt].v = p[lson].v + p[rson].v;
}
void updata(int rt,int pos, data v) {
    if (p[rt].l == pos && p[rt].r == pos) {
        p[rt].v = p[rt].v + v;
        return ;
    }
    int mid = (p[rt].l + p[rt].r) >> 1;
    if (pos <= mid) updata(lson, pos, v);
    if (pos > mid) updata(rson, pos, v);
    push_up(rt);
}
data find(int rt,int L, int R) {
    if (L <= p[rt].l && p[rt].r <= R) return p[rt].v;
    int mid = (p[rt].l + p[rt].r) >> 1;
    if (R <= mid) return find(lson, L, R);
    if (L > mid) return find(rson, L, R);
    return find(lson, L, R) + find(rson, L, R);
}
LL h[maxn*5], a[maxn];
int m;
int nxt[maxn];
int n, d;
int main(int argc, const char * argv[])
{    
    // freopen("in.txt","r",stdin);
    // freopen("out.txt","w",stdout);
    // ios::sync_with_stdio(false);
    // cout.sync_with_stdio(false);
    // cin.sync_with_stdio(false);

    cin >> n >> d;
    Rep(i, 1, n) {
        scanf("%lld", &a[i]);
        h[++m] = a[i];
        h[++m] = max(0LL, a[i] - d);
        h[++m] = a[i] + d;
    }
    sort(h + 1, h + 1 + m);
    m = unique(h + 1, h + 1 + m) - h - 1;
    build(1, 1, m);
    int res = 0;
    int o = 1;
    Rep(i, 1, n) {
        int l = lower_bound(h + 1, h + 1 + m, max(0LL, a[i] - d)) - h;
        int r = lower_bound(h + 1, h + 1 + m, a[i] + d) - h;
        data v = find(1, 1, l) + find(1, r, m);
        nxt[i] = v.loc;
        if (v.len + 1 > res) {
            res = v.len + 1;
            o = i;
        }
        int pos = lower_bound(h + 1, h + 1 + m, a[i]) - h;
        updata(1, pos, data(v.len + 1, i));
    }
    vector<int> vec;
    printf("%d\n", res);
    for (int u = o;u ; u = nxt[u])
        vec.push_back(u);
    for (int i = res - 1;i >= 0;--i)
        printf("%d ", vec[i]);
    puts("");

    // showtime;
    return 0;
}

Guess you like

Origin blog.csdn.net/KIJamesQi/article/details/52588793