普通平衡樹

題意:略,題中較清晰。

用二叉查找樹來存儲數據,為了增加效率,盡量使左子樹和右子樹的深度差不超過一,這樣可以時間控制在logn,效率比較高。

右旋和左旋,目的是為了維護二叉樹的操作,使其盡量平衡。

int n, m;
int o[N];
struct Node { // 節點int l, r; // 左兒子,右兒子int key, val; // 數據值,隨機值(用以維護二叉樹盡量平衡的條件) int cnt, size; // 當前key值的數量,當前子樹的所有節點的cnt值和
} tr[N];
int root, idx; // 根節點,下一個可以分配的節點序號void push_up(int p) { // 與線段樹操作的意義一樣tr[p].size = tr[tr[p].l].size + tr[tr[p].r].size + tr[p].cnt; // 左右子樹的size和加上本身cnt
}int get_node(int key) { // 創建一個節點,返回節點序號tr[++ idx].key = key; // 初始化keytr[idx].val = rand(); // 隨機一個01給valtr[idx].cnt = tr[idx].size = 1; // 數量為1,只有本身return idx; // 返回序號
}void build() { // 建立一個空的二叉樹,只有兩個哨兵,無窮大與無窮小get_node(-INF), get_node(INF);root = 1, tr[1].r = 2; push_up(root);
}void zig(int &p) { // 右旋int q = tr[p].l; // q為根節點左兒子tr[p].l = tr[q].r, tr[q].r = p, p = q; // 對應圖片分析push_up(tr[p].r), push_up(p); // 更新size值
}void zag(int &p) { // 左旋int q = tr[p].r; // q為根節點右兒子tr[p].r = tr[q].l, tr[q].l = p, p = q; // 對應圖片分析push_up(tr[p].l), push_up(p); // 更新size值
}void insert(int &p, int key) { // 插入一個節點keyif(!p) p = get_node(key); // 該key值未出現過,創建一個新的節點,并將序號返回到上一級else if(tr[p].key == key) tr[p].cnt ++; // 出現過,直接cnt數量加一else if(tr[p].key > key) { // 應該插在左兒子insert(tr[p].l, key); // 遞歸左兒子if(tr[tr[p].l].val > tr[p].val) zig(p); // 左兒子val值大于本身,右旋處理} else { // 應該插在右兒子insert(tr[p].r, key); // 遞歸右兒子if(tr[tr[p].r].val > tr[p].val) zag(p); // 右兒子var值大于本身,左旋處理}push_up(p); // 更新size狀態return ;
}void remove(int &p, int key) { // 刪除一個key值節點if(!p) return ; // 沒找到,直接結束if(tr[p].key == 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) {// 右兒子存在或者左兒子var值大于右兒子,右旋處理zig(p);remove(tr[p].r, key);// 右旋之后key值節點交換到當前p節點的右兒子,遍歷右兒子,一直遞歸直到沒有兒子的時候刪除} else {// 應該進行左旋處理zag(p);remove(tr[p].l, key);// 左旋之后key值節點交換到當前p節點的左兒子,遍歷左兒子,一直遞歸直到沒有兒子的時候刪除}} else p = 0; // 數量唯一且沒有兒子,直接刪除即可。} else if(tr[p].key > key) remove(tr[p].l, key); // key值點在左兒子else remove(tr[p].r, key); // key值點在右兒子push_up(p);
}int get_rank_by_key(int p, int key) { // 根據key值找排名if(!p) return 1;  // 沒找到直接return 1,因為洛谷這個題說的是不存在的數的排名為比它的數量加一if(tr[p].key == key) return tr[tr[p].l].size + 1; // 找到key值,返回key值在當前子樹的排名if(tr[p].key > key) return get_rank_by_key(tr[p].l, key);// key在左子樹return get_rank_by_key(tr[p].r, key) + tr[tr[p].l].size + tr[p].cnt; // key在右子樹,因為左子樹以及本身都是比它小的,所以需要加上這些數量,再去遞歸右子樹,計算key值在右子樹的排名
}
int get_key_by_rank(int p, int rank) {  // 找到排名為rank的key值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)); // 本身和右子樹都比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));  // 本身和左子樹都比key大,都有可能,遞歸左子樹與本身進行判斷。
}
inline void sovle() {build();
//	cout << idx << endl;cin >> n;while(n --) {int opt, x;cin >> opt >> x;if(opt == 1) insert(root, x);else if(opt == 2) remove(root, x);else if(opt == 3) cout << get_rank_by_key(root, x) - 1 << endl;else if(opt == 4) cout << get_key_by_rank(root, x + 1) << endl;else if(opt == 5) cout << get_prev(root, x) << endl;else cout << get_next(root, x) << endl;}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/162893.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/162893.shtml
英文地址,請注明出處:http://en.pswp.cn/news/162893.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Dubbo引入Zookeeper等注冊中心簡介以及DubboAdmin簡要介紹,為后續詳解Dubbo各種注冊中心做鋪墊!

文章目錄 一&#xff1a;Dubbo注冊中心引言 1&#xff1a;什么是Dubbo的注冊中心&#xff1f; 2&#xff1a;注冊中心關系圖解 3&#xff1a;引入注冊中心服務執行流程 4&#xff1a;Dubbo注冊中心好處 5&#xff1a;注冊中心核心作用 二&#xff1a;注冊中心實現方案 …

Springboot+vue的新冠病毒密接者跟蹤系統(有報告)。Javaee項目,springboot vue前后端分離項目

演示視頻&#xff1a; Springbootvue的新冠病毒密接者跟蹤系統(有報告)。Javaee項目&#xff0c;springboot vue前后端分離項目 項目介紹&#xff1a; 本文設計了一個基于Springbootvue的新冠病毒密接者跟蹤系統&#xff0c;采用M&#xff08;model&#xff09;V&#xff08;v…

HttpClient實現 get、post、put、delete請求【轉】

來自&#xff1a;HttpClient實現 get、post、put、delete請求_httpclient put請求-CSDN博客 目錄 HttpClient HttpClient的主要功能 httpclient使用示例主要步驟 Spring Boot 工程結構 HttpClient實現主要代碼&#xff1a; GET POST PUT Delete HttpClient HttpCli…

信息系統項目管理師-干系人管理論文提綱

快速導航 1.信息系統項目管理師-項目整合管理 2.信息系統項目管理師-項目范圍管理 3.信息系統項目管理師-項目進度管理 4.信息系統項目管理師-項目成本管理 5.信息系統項目管理師-項目質量管理 6.信息系統項目管理師-項目資源管理 7.信息系統項目管理師-項目溝通管理 8.信息系…

景區智慧旅游智能化系統方案:PPT全文58頁,附下載

關鍵詞&#xff1a;智慧景區解決方案&#xff0c;智慧文旅解決方案&#xff0c;智慧旅游解決方案&#xff0c;智慧文旅綜合運營平臺 一、景區智慧旅游智能化系統建設背景 近年來&#xff0c;隨著信息技術的快速發展和普及&#xff0c;以及旅游市場的不斷擴大和升級&#xff0…

電腦自動刪除文件怎么辦?如何恢復?

在數字化時代&#xff0c;電腦已經成為人們不可或缺的工具之一。然而&#xff0c;由于各種原因&#xff0c;我們有時會遇到電腦自動刪除文件的情況&#xff0c;這給我們的工作和生活帶來了很多不便。那么&#xff0c;當電腦自動刪除文件時&#xff0c;我們應該如何處理呢&#…

【Python爬蟲】8大模塊md文檔從0到scrapy高手,第8篇:反爬與反反爬和驗證碼處理

本文主要學習一下關于爬蟲的相關前置知識和一些理論性的知識&#xff0c;通過本文我們能夠知道什么是爬蟲&#xff0c;都有那些分類&#xff0c;爬蟲能干什么等&#xff0c;同時還會站在爬蟲的角度復習一下http協議。 Python爬蟲和Scrapy全套筆記直接地址&#xff1a; 請移步這…

數據結構與算法編程題14

設計一個算法&#xff0c;通過一趟遍歷在單鏈表中確定值最大的結點。 #include <iostream> using namespace std;typedef int Elemtype; #define ERROR 0; #define OK 1;typedef struct LNode {Elemtype data; //結點保存的數據struct LNode* next; //結構體指針…

RedHat NTP時間服務器配置Chrony(所有節點時間跟主節點時間同步)

NTP NTP&#xff08;Network Time Protocol&#xff09;是一種用于在計算機網絡中同步時鐘的協議。它的主要目的是確保網絡中的各個設備具有準確的時間參考&#xff0c;以便協調事件順序、安全通信和日志記錄等應用。它通過分層體系結構、時間同步算法和準確的時間參考源來確保…

Linux設置靜態IP

Linux設置靜態IP 使用ip addr查看ip&#xff0c;如下所示就是動態IP 1、什么是靜態IP&#xff1f; 靜態ip就是固定的ip&#xff0c;需要手動設置。靜態IP地址&#xff08;又稱固定IP地址&#xff09;是長期分配給一臺計算機或網絡設備使用的 IP 地址。一般來說&#xff0c;一…

【數據結構】C : 追星

C : 追星 文章目錄 C : 追星DescriptionInputOutputSampleInputOutput 解題思路AC代碼&#xff1a; Description 城市總共有N座。yintama是右京女神的狂熱粉&#xff0c;當他得知右京女神將要在城市N舉辦演唱會的時候&#xff0c;馬上開始準備動身前往城市N。原本他可以直接乘…

738. Monotone Increasing Digits 968. Binary Tree Cameras

738. Monotone Increasing Digits An integer has monotone increasing digits單調遞增數字 if and only if each pair of adjacent digits x and y satisfy x < y. Given an integer n, return the largest number that is less than or equal to n with monotone increa…

TypeScript 學習筆記 第三部分 貪吃蛇游戲

尚硅谷TypeScript教程&#xff08;李立超老師TS新課&#xff09; 1. 創建開發環境 創建工程&#xff0c;使用學習筆記的第二部分安裝css部分 npm i -D less less-loader css-loader style-loader對css部分處理&#xff0c;能夠運行在低版本瀏覽器 npm i -D postcss postcss…

oracle rac 19c修改不同網段public ip

客戶需求將才搭建的oracle 19.19數據庫從192.168.168.0網段調整到192.168.213網段 1.停止兩個節點集群 停止之前最好ocrdump一下&#xff0c;防止有問題 crsctl stop crs 2.修改public ip地址和/etc/hosts 3. 啟動crs 這時集群可以啟動&#xff0c;但是上面的一些資源啟動會…

音色逼真、韻律自然的AI人聲克隆限時福利!

聲音&#xff0c;為數字人注入靈魂。 2023云棲大會上&#xff0c;阿里云視頻云接受了CCTV-2財經頻道的采訪&#xff0c;分享并演示了如何利用云端智能剪輯&#xff0c;一站式完成數字人渲染及視頻精編二創。 正如視頻開頭所呈現的AI重現演員“原聲”&#xff0c;近年來&#x…

基于SpringBoot的圖書管理系統

基于SpringBoot的圖書管理系統 圖書管理系統開發技術功能模塊代碼結構數據庫設計運行截圖源碼獲取 圖書管理系統 開發技術 技術&#xff1a;SpringBoot、MyBatis-Plus、MySQL、Beetl、Layui。 框架&#xff1a;基于開源框架Snowy-Layui開發。 工具&#xff1a;IDEA、Navicat等…

【Linux】進程間通信——進程間通信的介紹和分類、管道、匿名管道、命名管道、匿名管道與命名管道的區別

文章目錄 進程間通信1.進程間通信的介紹1.1目的和發展 2.進程間通信分類3.管道3.1匿名管道3.1.1匿名管道的原理&#xff08;文件角度&#xff09;3.1.2匿名管道的原理&#xff08;內核角度&#xff09;3.1.3管道讀寫規則3.1.4管道特點 3.2命名管道3.2.1創建命名管道3.2.2命名管…

PTA-列出所有祖先結點

對于給定的二叉樹&#xff0c;本題要求你按從上到下順序輸出指定結點的所有祖先結點。 輸入格式: 首先第一行給出一個正整數 N&#xff08;≤10&#xff09;&#xff0c;為樹中結點總數。樹中的結點從 0 到 N?1 編號。 隨后 N 行&#xff0c;每行給出一個對應結點左右孩子的…

談思生物醫療直播 | 利用類器官模型研究肺的發育與穩態

類器官是一種三維細胞培養物&#xff0c;其在細胞類型&#xff0c;空間結構及生理功能上能夠模擬對應器官&#xff0c;從而提供一個高度生理相關的系統。自2009年小腸類器官首次建立至今&#xff0c;類器官研究已經延伸到多個組織系統&#xff0c;并成為當下生命科學領域最熱門…

element plus 使用細節

菜鳥一直在糾結這個寫不寫&#xff0c;因為不難&#xff0c;但是菜鳥老是容易忘記&#xff0c;雖然想想或者搜搜就可以馬上寫出來&#xff0c;但是感覺每次那樣就太麻煩了&#xff0c;不如一股做氣寫了算了&#xff0c;后面遇見別的就再來補充&#xff01; 文章目錄 table 表格…