POJ 1442 平衡樹Treap新模板
題意:輸入m個數,詢問n個數,第一個數如果是3,就輸出在m的第三個數輸入完成後第1大的數,第二個就輸出第二大的數,但前提都是在輸入完U[i]個數後
思路:用平衡樹Treap進行插入和查詢第K大的數,模版題
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; const int maxn=100010; class Treap{ public: struct Treap_Node{ Treap_Node *left,*right; int value,fix,weight,size;//fix為修正值,是隨機產生的,保證二叉樹不會退化的重要環節,wweight為權值,size為子樹大小 }*root,*null; Treap(){ null=new struct Treap_Node; null->size=0; null->weight=0; null->value=inf; null->left=null; null->right=null; null->fix=inf; root=null; } void Treap_Print(Treap_Node *P){//從小到大輸出 if(P!=null){ Treap_Print(P->left); printf("%d\n",P->value); Treap_Print(P->right); } } void Treap_Left_Rotate(Treap_Node *&a){//左旋之後仍不改變二叉樹性質 Treap_Node *b=a->right; a->right=b->left; b->left=a; b->size=a->size; a->size=a->left->size+a->right->size+a->weight; a=b; } void Treap_Right_Rotate(Treap_Node *&a){//右旋之後仍不改變二叉樹性質 Treap_Node *b=a->left; a->left=b->right; b->right=a; b->size=a->size; a->size=a->left->size+a->right->size+a->weight; a=b; } int Treap_Find(Treap_Node *P,int value){//查詢有沒有value這個數 if(P==null) return 0; if(P->value==value) return 1; else if(value<P->value) return Treap_Find(P->left,value); else return Treap_Find(P->right,value); } void Treap_Insert(Treap_Node *&P,int value){//插入一個數 if(P==null){ P=new Treap_Node; P->left=P->right=null;//左右兒子均為空 P->value=value; P->fix=rand(); P->weight=1; P->size=1; }else if(value==P->value){ P->weight++; } else if(value<P->value){ Treap_Insert(P->left,value); if(P->left->fix<P->fix) Treap_Right_Rotate(P); }else{ Treap_Insert(P->right,value); if(P->right->fix<P->fix) Treap_Left_Rotate(P); } P->size=P->left->size+P->right->size+P->weight; } void Treap_Delete(Treap_Node *&P,int value){//刪除一個數 if(P==null) return ; if(value<P->value) Treap_Delete(P->left,value); else if(value>P->value) Treap_Delete(P->right,value); else if(P->weight>1) P->weight--; else if((P->left==NULL)&&(P->right==NULL)){ delete P; P=NULL; }else{ if(P->left->fix<P->right->fix) Treap_Left_Rotate(P); else Treap_Right_Rotate(P); Treap_Delete(P,value); } P->size=P->left->size+P->right->size+P->weight; } int Treap_pred(Treap_Node *P,int value,Treap_Node *optimal){//前驅 if(P==null||value==P->value) return optimal->value; if(P->value<value) return Treap_pred(P->right,value,P); else return Treap_pred(P->left,value,optimal); } int Treap_succ(Treap_Node *P,int value,Treap_Node *optimal){//後繼 if(P==null||value==P->value) return optimal->value; if(P->value>value) return Treap_succ(P->left,value,P); else return Treap_succ(P->right,value,optimal); } int Treap_Findkth(Treap_Node *P,int k){//求第K大的數 if(P==null) return 0; int t=P->left->size; if(k<t+1) return Treap_Findkth(P->left,k); else if(k>t+P->weight) return Treap_Findkth(P->right,k-(t+P->weight)); else return P->value; } int Treap_Rank(Treap_Node *P,int value,int cur){//求這個數的排名 int t=P->left->size; if(value==P->value) return t+cur+1; else if(value<P->value) return Treap_Rank(P->left,value,cur); else return Treap_Rank(P->right,value,t+cur+P->weight); } void Treap_erase(Treap_Node *&P) {//將樹清空 if(P->left!=null) Treap_erase(P->left); if(P->right!=null) Treap_erase(P->right); delete P; } }; int num[30010],num1[50010]; int main(){ int n,a,b,m; while(scanf("%d%d",&n,&m)!=-1){ Treap tree; for(int i=1;i<=n;i++) scanf("%d",&num[i]); int t=1,k=1; for(int i=1;i<=m;i++) scanf("%d",&num1[i]); while(t<=m){ while(k<=num1[t]){ tree.Treap_Insert(tree.root,num[k]); k++; } int ans=tree.Treap_Findkth(tree.root,t++); printf("%d\n",ans); } } return 0; }
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3fll; const int maxn=15010; struct Node{ Node *ch[2]; int r,v,s; Node(int v):v(v){ch[0]=ch[1]=NULL;r=rand();s=1;} int cmp(int x){ if(x==v) return -1; return x<v? 0:1; } void maintain(){ s=1; if(ch[0]!=NULL) s+=ch[0]->s; if(ch[1]!=NULL) s+=ch[1]->s; } }; void Rotate(Node* &o,int d){ Node* k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o; o->maintain();k->maintain();o=k; } void Insert(Node* &o,int x){ if(o==NULL) o=new Node(x); else{ int d=x<(o->v)? 0:1; Insert(o->ch[d],x); if(o->ch[d]->r>o->r) Rotate(o,d^1); } o->maintain(); } void Remove(Node* &o,int x){ int d=o->cmp(x); if(d==-1){ Node* u=o; if(o->ch[0]!=NULL&&o->ch[1]!=NULL){ int d2=(o->ch[0]->r>o->ch[1]->r?1:0); Rotate(o,d2);Remove(o->ch[d2],x); }else{ if(o->ch[0]==NULL) o=o->ch[1]; else o=o->ch[0]; delete u; } }else Remove(o->ch[d],x); if(o!=NULL) o->maintain(); } int Kth(Node* &o,int k){//第K大的值 if(o==NULL||k<=0||k>o->s) return 0; int s=(o->ch[0]==NULL?0:o->ch[0]->s); if(k==s+1) return o->v; else if(k<=s) return Kth(o->ch[0],k); else return Kth(o->ch[1],k-s-1); } int Rank(Node* &o,int x){//x的排名 if(o==NULL) return -1;//未找到 int num=o->ch[0]==NULL?0:o->ch[0]->s; if(x==o->v) return num+1; else if(x<o->v) return Rank(o->ch[0],x); else return Rank(o->ch[1],x)+num+1; } void deletetree(Node* &o){ if(o->ch[0]!=NULL) deletetree(o->ch[0]); if(o->ch[1]!=NULL) deletetree(o->ch[1]); delete o;o=NULL; } int num[30010],num1[50010]; int main(){ int n,m,a,b; while(scanf("%d%d",&n,&m)!=-1){ Node* root=NULL; for(int i=1;i<=n;i++) scanf("%d",&num[i]); for(int i=1;i<=m;i++) scanf("%d",&num1[i]); int t=1,k=1; while(t<=m){ while(k<=num1[t]){ Insert(root,num[k]); k++; } int ans=Kth(root,t++); printf("%d\n",ans); } deletetree(root); } return 0; }
相關推薦
POJ 1442 平衡樹Treap新模板
題意:輸入m個數,詢問n個數,第一個數如果是3,就輸出在m的第三個數輸入完成後第1大的數,第二個就輸出第二大的數,但前提都是在輸入完U[i]個數後 思路:用平衡樹Treap進行插入和查詢第K大的數,模版題 #include <stdio.h> #include
平衡樹Treap模板與原理
優化 排名 print 比較 pla ans for 後繼 每一個 這次我們來講一講Treap(splay以後再更) 平衡樹是一種排序二叉樹(或二叉搜索樹),所以排序二叉樹可以迅速地判斷兩個值的大小,當然操作肯定不止那麽多(不然我們還學什麽)。 而平衡樹在排序二叉樹的基礎上
luoguP3369[模板]普通平衡樹(Treap/SBT) 題解
names main getchar() clu 父親節 ble blank fine while 鏈接一下題目:luoguP3369[模板]普通平衡樹(Treap/SBT) #include<iostream> #include<cstdlib>
【模板】平衡樹——Treap和Splay
二叉搜尋樹($BST$):一棵帶權二叉樹,滿足左子樹的權值均小於根節點的權值,右子樹的權值均大於根節點的權值。且左右子樹也分別是二叉搜尋樹。(如下) $BST$的作用:維護一個有序數列,支援插入$x$,刪除$x$,查詢排名為$x$的數,查詢$x$的排名,求$x$的前驅後繼等操作。 時間複雜度:$O(運
【模板】普通平衡樹 Treap
題目描述 您需要寫一種資料結構(可參考題目標題),來維護一些數,其中需要提供以下操作: 1.插入x數 2.刪除x數(若有多個相同的數,因只刪除一個) 3.查詢x數的排名(排名定義為比當前數小的數的個數+1。若有多個相同的數,因輸出最小的排名) 4.查詢
【bzoj3224】普通平衡樹——treap
blog lib mes cas style tree upd treap ins 我的第一道treap題目,treap的模版題。 代碼是對著hzw的敲的,一邊敲一邊理解。。。 主要是熟悉一下treap的各種基本操作,詳細細節看代碼。 #include<cstdio
3224: Tyvj 1728 普通平衡樹(新板子)
pri ati urn 多個 stdin 目標 一個 題目 page 3224: Tyvj 1728 普通平衡樹 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 17048 Solved: 7429[Submit][S
bzoj3224Tyvj 1728 普通平衡樹 treap
amp turn clas algo 。。 pac rip problem upd 3224: Tyvj 1728 普通平衡樹Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 17706 Solved: 7764[Submit
[洛谷P3369] 普通平衡樹 Treap & Splay
mes href using oid org 題目 scanf printf std 這個就是存一下板子...... 題目傳送門 Treap的實現應該是比較正經的。 插入刪除前驅後繼排名什麽的都是平衡樹的基本操作。 1 #include<cstdio>
7.Bzoj3224: Tyvj 1728 普通平衡樹(Treap)
Bzoj3224: Tyvj 1728 普通平衡樹(Treap) 終於自己敲出來了Treap。。。。。。拿來當板子還是挺好用的. 操作1,顯然根據二叉搜尋樹的性質直接建就好了. 操作2,如果有兩個兒子,則把這個點下旋下去,直到只有一個兒子或者沒有. 操作3,查詢比他小的數,記錄一個size,表示這個點有多少
poj 3691(AC自動機,新模板)
.題意是說給了N個帶病毒的DNA串( DNA串只有AGCT幾種單元組成)...再給一長串DNA..問這長串DNA最少改動幾個(就是改..不是刪除或者新增..)能保證沒有包含病毒字串..輸出這個最小改動的次數..若怎麼修改都帶病毒子串...輸出-1... 思路:這是我第一道調
資料結構之平衡樹(Treap)
平衡樹是二叉搜尋樹和堆合併構成的新資料結構,所以它的名字取了Tree和Heap各一半,叫做Treap。 堆和樹的性質是衝突的,二叉搜尋樹滿足左子樹<根節點<右子樹,而堆是滿足根節點小於等於(或大於等於)左右兒子。因此在Treap的資料結構中,並不是
POJ 3107 Godfather (樹的重心模板題)
題意:給出一棵樹,求出所有樹的重心,並且按編號從小到大輸出。 直接套模板即可。 程式碼如下: #include<iostream> #include<cstdio> #inc
最強平衡樹——Treap[以我的最弱擊敗你的最強]
僕の最弱を以て,君の最強を打ち破る。!!——Treap 本人蒟蒻,在平衡樹坑中深陷數年。為了早日逃離此天坑,特作此文。 什麼是平衡樹?度娘傳送門 什麼是treap?ACdreamers%%% 注:本篇所有程式碼都在片尾!!(醒目) CMP 那麼瞭解了
BZOJ 1208 平衡樹Treap模版題
題意:不描述了 思路:我們只需要一個樹就可以,輸入一個數就存進去,當人和動物都大於0的時候,開始給人分配寵物,人的期望值b的排名k,找到k-1的數和k+1的數,比較哪個離b更近,人多還是動物動情況一樣不用分開討論,然後加起來取餘輸出,簡單題#include <std
洛谷P3369 普通平衡樹(Treap/Splay)
題目描述 您需要寫一種資料結構(可參考題目標題),來維護一些數,其中需要提供以下操作: 1. 插入x數 2. 刪除x數(若有多個相同的數,因只刪除一個) 3. 查詢x數的排名(若有多個相同的數,因輸出最小的排名) 4. 查詢排名為x的數 5.
紅黑樹 ------ luogu P3369 【模板】普通平衡樹(Treap/SBT)
div child lin main false tchar clas char als 二次聯通門 : luogu P3369 【模板】普通平衡樹(Treap/SBT) 近幾天閑來無事。。。就把各種平衡樹都寫了一下。。。 下面是紅黑樹(Red Black Tree)
替罪羊樹 ------ luogu P3369 【模板】普通平衡樹(Treap/SBT)
nod %d clas https number problem 普通 true ble 二次聯通門 : luogu P3369 【模板】普通平衡樹(Treap/SBT) 閑的沒事,把各種平衡樹都寫寫 比較比較。。。 下面是替罪羊樹 #include &l
數組splay ------ luogu P3369 【模板】普通平衡樹(Treap/SBT)
普通 模板 char truct div color fine col suffix 二次聯通門 : luogu P3369 【模板】普通平衡樹(Treap/SBT) #include <cstdio> #define Max 100005
fhq treap ------ luogu P3369 【模板】普通平衡樹(Treap/SBT)
ret true read std stdin urn tdi ref code 二次聯通門 : LibreOJ #104. 普通平衡樹 #include <cstdio> #include <iostream> #include