Codeforces 573E

Provided $ f_ {i, j} $ $ I $ is deleted before the number of $ $ j th maximum value, the metastasis $ f_ {i, j} = max (f_ {i-1, j}, f_ { i-1, j-1} + a_i) $.

Proven, we found that for each $ a_i $, there is a $ j $, for all $ dp $ value after the $ j $ and $ j $ are selected on the $ a_i $.

Thus maintenance $ $ DP with a balanced tree, that is updated every time a new point is added, for a section for adding interval arithmetic sequence, a demarcation point to two points, the complexity of $ O (nlog ^ 2n) $.

 #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
namespace {
    struct node {
        int f, sz, ch[2];
        ll v, d, a;
    } t[maxn];
    int root = 1, Pool = 1;
    void update(int x) {
        t[x].sz = t[t[x].ch[0]].sz + t[t[x].ch[1]].sz + 1;
    }
    bool wh(int x) {
        return x == t[t[x].f].ch[1];
    }
    void modify(int x, ll a, ll d) {
        t[x].d += d;
        t[x].a += a;
        t[x].v += a + d * (t[t[x].ch[0]].sz + 1);
    }    
    void Pushdown(int x) {
        if(!t[x].d && !t[x].a) return;
        if(t[x].ch[0]) modify(t[x].ch[0], t[x].a, t[x].d);
        if(t[x].ch[1]) modify(t[x].ch[1], t[x].a + t[x].d * (t[t[x].ch[0]].sz + 1), t[x].d);
        t[x].a = t[x].d = 0;
    }
    void Push(int x) {
        if(t[x].f) Push(t[x].f);
        Pushdown(x);
    }
    void rotate(int x) {
        int f = t[x].f, w = wh(x);
        t[x].f = t[f].f;
        t[t[f].f].ch[wh(f)] = x;
        t[f].ch[w] = t[x].ch[w ^ 1];
        t[t[x].ch[w ^ 1]].f = f;
           t[x].ch[w ^ 1] = f;
        t[f].f = x;
        update(f);
        update(x);
    }
    inline void splay(int x, int tar) {
        Push(x);
        for(; t[x].f != tar; rotate(x))
            if(t[t[x].f].f != tar) 
                rotate(wh(x) == wh(t[x].f) ? t[x].f : x);
           if(!tar) root = x;      
    }
    ll find_k(int k) {
        int x = root;
        while(1) {
            if(t[x].ch[0] && t[t[x].ch[0]].sz >= k) x = t[x].ch[0];
            else if(t[t[x].ch[0]].sz + 1 < k) k -= t[t[x].ch[0]].sz + 1, x = t[x].ch[1];
            else { splay(x, 0); return t[x].v; }
        }
    }
    void Insert() {
        t[++Pool].v = t[root].v;
        t[Pool].f = root;
        t[t[root].ch[1]].f = Pool;
        t[Pool].ch[1] = t[root].ch[1];
        t[root].ch[1] = Pool;
    }
    int Query(int i, int x) {
        int l = 0, r = i, ret = i;
        while(r - l > 1) {
            int mid = l + r >> 1;
            if(find_k(mid) + 1LL * mid * x > find_k(mid + 1)) r = ret = mid;
            else l = mid;
        }
        return ret;
    }
    ll dfs(int x) {
        if(!x) return (ll)(-1e18);
        Pushdown(x);
        return max(max(dfs(t[x].ch[0]), dfs(t[x].ch[1])), t[x].v);
    }
}
int n;
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) {
        int x, k; scanf("%d", &x);
        k = Query(i, x);
        find_k(k);
        Insert();
        modify(Pool, 1LL * (k - 1) * x, x);
    }
    printf("%lld\n", dfs(root));
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/2-321414133115/p/11330215.html