アルゴリズム競争の高度なガイド--- 0x49(バランスツリー)売上高統計

トピック

ここに画像の説明を挿入

入力サンプル

6
5
1
2
5
4
6

サンプル出力

12

ここに画像の説明を挿入

回答

  1. この質問の意味は、aiの場合、最初のi番号の中でaiとの差が最も小さい番号を見つけることです。それを行う方法はまだたくさんあります。set、隣接リスト、またはtreapを使用して直接行うことができます。 、コードはtreapです
  2. この問題は、treapを使用して先行を見つけ(ここでは、equalが最適解であり、テンプレートコードは特定のものに依存するため、厳密には以下ではありません)、次に後続(厳密には以下)を見つけて、先行および後続と現在の値の差値は最小です
  3. それはまだ平衡二分木のテンプレートなので、ここでは説明しませんテンプレートについては、ここをクリックしてください

コード

#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;
}

おすすめ

転載: blog.csdn.net/qq_44791484/article/details/113814021