2019 멀티 - 대학 교육 대회 3 - 책의 D 배포

균형 이진 트리 답변 + + DP

물론 절반의 질문에 대한 대답은, DP 각각 우리의 가장 큰 각 그룹의 절반은 감지한다.

i가 분할 될 수 예약 전에 DP는 [i]는 그룹의 최대 수를 나타낸다.

(- 합 [J] <= 중간 합계 [I])과 합 프리픽스 전이 상태 방정식을 DP [I] = 최대 (DP [J]) + 1을 얻을 수있다.

분명히 이것은 N ^ 2, 최적화를 고려해야합니다.

당신은 균형 잡힌 트리, 각 노드를 구축하고 접두사, DP 값을 유지할 수 있습니다, 그것은 가장 큰 하위 트리 DP 값이었다.

중간 - 우리는 DP의 최대 값을 찾고 있습니다 전에뿐만 아니라 수식 합 [J]> = 합 [내가]를받을 경우 제한 접두사가 변경됩니다 충족

우리는 합계를 찾아, 균형 잡힌 트리를 유지하여 값을 요약 할 수 있습니다 [I] - 중간 후속 노드, 그래서 오른쪽 하위 트리 노드와 노드 (DP)의 값을 찾을 수있는 인덱스입니다.

한 직접 다시 노드의 최대 값 DP DP 최대 값과 하위 트리가 될 수있다, 당신은 신속하게 답을 찾을 수 있도록 각 노드는 하위 트리 DP 최대 값을 유지하자.

이 노드는 시간 지점은 팔 굽혀 펴기 당김 달성 될 수 삽입된다.

내가 직접 잘 루트에 후속 스플레이에, 그것은 매우 편리 찾아 스플레이를 사용합니다.

#include <bits/stdc++.h>
#define INF 233333333333333333
#define full(a, b) memset(a, b, sizeof a)
#define FastIn ios::sync_with_stdio(false), cin.tie(0)
#define pb push_back
using namespace std;
typedef long long LL;
inline int lowbit(int x){ return x & (-x); }
inline int read(){
    int ret = 0, w = 0; char ch = 0;
    while(!isdigit(ch)){
        w |= ch == '-', ch = getchar();
    }
    while(isdigit(ch)){
        ret = (ret << 3) + (ret << 1) + (ch ^ 48);
        ch = getchar();
    }
    return w ? -ret : ret;
}
inline int lcm(int a, int b){ return a / __gcd(a, b) * b; }
template <typename A, typename B, typename C>
inline A fpow(A x, B p, C lyd){
    A ans = 1;
    for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
    return ans;
}
const int N = 300005;
int _, n, k, a[N], tot, ch[N][2], mxid[N], id[N], fa[N], root, dp[N];
LL pre[N], lower, upper, val[N];

void go(){
    root = 0, tot = 0;
}

inline int build(LL v, int i, int f){
    ++ tot;
    val[tot] = v, mxid[tot] = id[tot] = i;
    fa[tot] = f, ch[tot][0] = ch[tot][1] = 0;
    return tot;
}

inline void push_up(int rt){
    mxid[rt] = id[rt];
    if(ch[rt][0]) mxid[rt] = max(mxid[rt], mxid[ch[rt][0]]);
    if(ch[rt][1]) mxid[rt] = max(mxid[rt], mxid[ch[rt][1]]);
}

inline void rotate(int x){
    int y = fa[x], z = fa[y], p = (ch[y][1] == x) ^ 1;
    ch[y][p ^ 1] = ch[x][p], fa[ch[x][p]] = y;
    ch[z][ch[z][1] == y] = x, fa[x] = z;
    ch[x][p] = y, fa[y] = x;
    push_up(y), push_up(x);
}

inline void splay(int x, int goal){
    while(fa[x] != goal){
        int y = fa[x], z = fa[y];
        if(z != fa[y]){
            (ch[y][0] == x) ^ (ch[z][0] == y) ? rotate(x) : rotate(y);
        }
        rotate(x);
    }
    push_up(x);
    if(goal == 0) root = x;
}

inline void insert(LL x, int i){
    if(!root){
        root = build(x, i, 0);
        return;
    }
    int cur = root;
    while(ch[cur][x > val[cur]]){
        if(val[cur] == x) break;
        cur = ch[cur][x > val[cur]];
    }
    if(val[cur] == x) id[cur] = max(id[cur], i), splay(cur, 0);
    else ch[cur][x > val[cur]] = build(x, i, cur), splay(ch[cur][x > val[cur]], 0);
}

inline void find(LL x){
    int cur = root;
    while(ch[cur][x > val[cur]] && val[cur] != x)
        cur = ch[cur][x > val[cur]];
    splay(cur, 0);
}

inline int successor(LL x){
    find(x);
    if(val[root] >= x) return root;
    int cur = ch[root][1];
    while(ch[cur][0]) cur = ch[cur][0];
    return cur;
}

inline int solve(LL x){
    splay(successor(x), 0);
    return max(id[root], mxid[ch[root][1]]);
}

inline bool calc(LL mid){
    go();
    insert(INF, 0);
    for(int i = 1; i <= n; i ++){
        int tmp = solve(pre[i] - mid);
        if(tmp == 0 && pre[i] > mid) continue;
        dp[i] = tmp + 1;
        if(dp[i] >= k) return true;
        insert(pre[i], dp[i]);
    }
    return false;
}

int main(){

    //freopen("data.txt", "r", stdin);
    for(_ = read(); _; _ --){
        n = read(), k = read();
        for(int i = 1; i <= n; i ++){
            a[i] = read();
            if(a[i] < 0) lower += a[i];
            else upper += a[i];
            pre[i] = pre[i - 1] + a[i];
        }
        LL l = lower, r = upper;
        while(l < r){
            LL mid = (l + r) >> 1;
            if(calc(mid)) r = mid;
            else l = mid + 1;
        }
        cout << l << endl;
    }

    return 0;
}

추천

출처www.cnblogs.com/onionQAQ/p/11272277.html