日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

AcWing 253. 普通平衡树

發布時間:2023/12/3 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AcWing 253. 普通平衡树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

您需要寫一種數據結構(可參考題目標題),來維護一些數,其中需要提供以下操作:

  • 插入數值x。
  • 刪除數值x(若有多個相同的數,應只刪除一個)。
  • 查詢數值x的排名(若有多個相同的數,應輸出最小的排名)。
  • 查詢排名為x的數值。
  • 求數值x的前驅(前驅定義為小于x的最大的數)。
  • 求數值x的后繼(后繼定義為大于x的最小的數)。
    注意: 數據保證查詢的結果一定存在。
    本題為平衡樹基本操作的代碼實現
  • #include <cstdio> #include <cstring> #include <iostream> #include <algorithm>using namespace std;const int N = 100010, INF = 1e8;int n; struct Node {int l, r;int key, val;int cnt, size; }tr[N];int root, idx;void pushup(int p) {tr[p].size = tr[tr[p].l].size + tr[tr[p].r].size + tr[p].cnt; }int get_node(int key) {tr[ ++ idx].key = key;tr[idx].val = rand();tr[idx].cnt = tr[idx].size = 1;return idx; }void zig(int &p) // 右旋 {int q = tr[p].l;tr[p].l = tr[q].r, tr[q].r = p, p = q;pushup(tr[p].r), pushup(p); }void zag(int &p) // 左旋 {int q = tr[p].r;tr[p].r = tr[q].l, tr[q].l = p, p = q;pushup(tr[p].l), pushup(p); }void build() {get_node(-INF), get_node(INF);root = 1, tr[1].r = 2;pushup(root);if (tr[1].val < tr[2].val) zag(root); }void insert(int &p, int key) {if (!p) p = get_node(key);else if (tr[p].key == key) tr[p].cnt ++ ;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);}pushup(p); }void remove(int &p, int key) {if (!p) return;if (tr[p].key == key){if (tr[p].cnt > 1) tr[p].cnt -- ;else if (tr[p].l || tr[p].r){if (!tr[p].r || tr[tr[p].l].val > tr[tr[p].r].val){zig(p);remove(tr[p].r, key);}else{zag(p);remove(tr[p].l, key);}}else p = 0;}else if (tr[p].key > key) remove(tr[p].l, key);else remove(tr[p].r, key);pushup(p); }int get_rank_by_key(int p, int key) // 通過數值找排名 {if (!p) return 0; // 本題中不會發生此情況if (tr[p].key == key) return tr[tr[p].l].size + 1;if (tr[p].key > key) return get_rank_by_key(tr[p].l, key);return tr[tr[p].l].size + tr[p].cnt + get_rank_by_key(tr[p].r, key); }int get_key_by_rank(int p, int rank) // 通過排名找數值 {if (!p) return INF; // 本題中不會發生此情況if (tr[tr[p].l].size >= rank) return get_key_by_rank(tr[p].l, rank);if (tr[tr[p].l].size + tr[p].cnt >= rank) return tr[p].key;return get_key_by_rank(tr[p].r, rank - tr[tr[p].l].size - tr[p].cnt); }int get_prev(int p, int key) // 找到嚴格小于key的最大數 {if (!p) return -INF;if (tr[p].key >= key) return get_prev(tr[p].l, key);return max(tr[p].key, get_prev(tr[p].r, key)); }int get_next(int p, int key) // 找到嚴格大于key的最小數 {if (!p) return INF;if (tr[p].key <= key) return get_next(tr[p].r, key);return min(tr[p].key, get_next(tr[p].l, key)); }int main() {build();scanf("%d", &n);while (n -- ){int opt, x;scanf("%d%d", &opt, &x);if (opt == 1) insert(root, x);else if (opt == 2) remove(root, x);else if (opt == 3) printf("%d\n", get_rank_by_key(root, x) - 1);else if (opt == 4) printf("%d\n", get_key_by_rank(root, x + 1));else if (opt == 5) printf("%d\n", get_prev(root, x));else printf("%d\n", get_next(root, x));}return 0; }

    Vector版偷懶平衡樹

    #include<cstdio> #include<vector> #include<algorithm> using namespace std; vector<int>v; int n,opt,x; int main() {v.reserve(100001);scanf("%d",&n);while(n--){scanf("%d%d",&opt,&x);if(opt==1) v.insert(lower_bound(v.begin(),v.end(),x),x);if(opt==2) v.erase (lower_bound(v.begin(),v.end(),x));if(opt==3) printf("%d\n",lower_bound(v.begin(),v.end(),x)-v.begin()+1);if(opt==4) printf("%d\n",v[x-1]);if(opt==5) printf("%d\n",v[lower_bound(v.begin(),v.end(),x)-v.begin()-1]);if(opt==6) printf("%d\n",v[upper_bound(v.begin(),v.end(),x)-v.begin()]);}return 0; }

    總結

    以上是生活随笔為你收集整理的AcWing 253. 普通平衡树的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。