Advanced Guide to Algorithm Competition---0x49 (Balanced Tree) Turnover Statistics

Topic

Insert picture description here

Input sample

6
5
1
2
5
4
6

Sample output

12

Insert picture description here

answer

  1. The meaning of this question is that for ai, find a number with the smallest difference from ai among the first i numbers. There are still many ways to do it. We can do it directly with set, or with adjacency list, or with treap, The code is treap
  2. This problem is to use treap to find a predecessor (here is not strictly less than, because equal is the optimal solution, the template code depends on the specific), and then find a successor (not strictly greater than), and then judge the difference between the predecessor and successor and the current value The value is the smallest
  3. Because it is still the template of the balanced tree, I won’t explain it here. Click here to see the template

Code

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>

using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int INF = 1e7;

int n, a;
int root, idx;

struct Node {
    
    
    int l, r;
    int key, val;
} tr[N];


int get_node(int key) {
    
    
    tr[++idx].key = key;
    tr[idx].val = rand();
    return idx;
}

void zig(int &p) {
    
      //右旋
    int q = tr[p].l;
    tr[p].l = tr[q].r, tr[q].r = p, p = q;
}

void zag(int &p) {
    
     //左旋
    int q = tr[p].r;
    tr[p].r = tr[q].l, tr[q].l = p, p = q;
}

void build() {
    
    
    get_node(-INF);
    get_node(INF);
    root = 1;
    tr[1].r = 2;
    if (tr[2].val > tr[1].val) zag(root);
}

void insert(int &p, int key) {
    
    
    if (!p) p = get_node(key);
    else if (tr[p].key == key) return;
    else if (tr[p].key > key) {
    
    
        insert(tr[p].l, key);
        if (tr[tr[p].l].val > tr[p].val) zig(p);
    } else {
    
    
        insert(tr[p].r, key);
        if (tr[tr[p].r].val > tr[p].val) zag(p);
    }
}

int get_prev(int p, int key) {
    
       //找前驱
    if (!p) return -INF;
    else if (tr[p].key == key) return tr[p].key;
    if (tr[p].key >= key) return get_prev(tr[p].l, key);
    else return max(tr[p].key, get_prev(tr[p].r, key));
}

int get_next(int p, int key) {
    
      //找后继
    if (!p) return INF;
    else if (tr[p].key == key) return tr[p].key;
    if (tr[p].key <= key) return get_next(tr[p].r, key);
    else return min(tr[p].key, get_next(tr[p].l, key));
}


int main() {
    
    

    build();
    cin >> n;
    ll res = 0;
    for (int i = 1; i <= n; i++) {
    
    
        cin >> a;
        if (i == 1) {
    
    
            res += a;
        } else {
    
    
            res += min(abs(a - get_prev(root, a)), abs(get_next(root, a) - a));
        }
        insert(root, a);
    }
    cout << res << endl;

    return 0;
}

Guess you like

Origin blog.csdn.net/qq_44791484/article/details/113814021