Treap模板(第K大,插入刪除查找)

#include <time.h>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
//By sssSSSay
//On 2017 . 2 . 6
//Today White Eve
#define Lc (o -> Ch[0])
#define Rc (o -> Ch[1])
#define val (o -> v)
#define pre (o -> p)
#define siz (o -> S)
//I'm So Lazy Oh Yes
using namespace std;

const int Maxn = 10001;

struct Treap{
    Treap* Ch[2];//The Node's Two Child Tree
    int p,v,S;//Priority Value And Size
};

int root = 0,n,x,a[Maxn];

void Update(Treap* &o){//Mountain O's Size
    siz = 1;
    if(Lc != NULL)siz += Lc -> S;
    if(Rc != NULL)siz += Rc -> S;
}

void Rotate(Treap* &o,int d){
    Treap* P = o -> Ch[d^1];//P Is A Point That Willing To Be A Root
    o -> Ch[d^1] = P -> Ch[d];//Eh......Rotate Should Give P's Child To O
    P -> Ch[d] = o;//O Is Going Down So It Is P's Child
    Update(o);Update(P);//Points' Size Has Been Changed
    o = P;//Use P To Replace O
}

void Insert(Treap* &o,int x){
    if(o == NULL){//Insert It To Leaves
        o = new Treap();
        Lc = Rc = NULL;
        pre = rand();val = x;
    }
    else {//Rotate And Let x Going Up
         int d = x < val;
         Insert(o -> Ch[d],x);
         if( ( pre ) > o -> Ch[d] -> p)Rotate(o,d^1);
    }
    Update(o);//Mountain O's Size
}

int Find(Treap* o,int x){
    while(o != NULL){
        if(val == x)return 1;
        o = (x < val) ? Rc : Lc ;//Oh It's Easy
    }return 0;
}

void Delete(Treap* &o,int x){
    if(val == x){//If Find Out X 
        if(Lc == NULL)o = Rc;
        else if(Rc == NULL)o = Lc;//Link Child To Father Straight
        else {
            int T = (Lc -> p) < (Rc -> p);//Search A Child Tree That Has A Less Pre
            Rotate(o,T);Delete(o -> Ch[T],x);//Rotate It And Delete It In Child Tree
        }
    }
    else Delete(o -> Ch[x < val],x);
    if(o != NULL)Update(o);
}

int Kth_Min(Treap* o,int k){
    if(o == NULL || k <= 0 || k > siz)return 0;//Clearly Can't Find Kth Cases
    int S = (Rc == NULL) ? 0 : (Rc -> S);//A Half's Size
    if(k == S + 1)return val;//Has Found It
    else if(k <= S)return Kth_Min(Rc,k);//Find It In Child Tree
    else return Kth_Min(Lc,k - S - 1);
}

int Kth_Max(Treap* o,int k){//The Same As Above
    if(o == NULL || k <= 0 || k > siz)return 0;
    int S = (Lc == NULL) ? 0 : (Lc -> S);
    if(k == S + 1)return val;
    else if(k <= S)return Kth_Max(Lc,k);
    else return Kth_Max(Rc,k - S - 1);    
}

void Print(Treap* o){//Print A Tree
    printf("%d ",siz);
    if(Lc != NULL)Print(Lc);
    if(Rc != NULL)Print(Rc);
}

int main(){
    srand(time(NULL));
    scanf("%d",&n);
    Treap* Root = NULL;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        // if(Root != NULL)printf("%d\n",Root -> v);
        Insert(Root,a[i]);
    }

    // printf("%d %d\n",Root -> v,Root -> p);
    // Print(Root);
    // Print ==> Print A Treap

    // while(true){
    //     int J = 0;
    //     scanf("%d%d",&J,&x);
    //     if(J == 1)printf("%d\n",Find(Root,x));
    //     else Delete(Root,x);
    // }
    // Debug -- Find If Exist And If Delete Is Right

    // while(true){
    //     scanf("%d",&x);
    //     printf("%d %d\n",Kth_Min(Root,x),Kth_Max(Root,x));
    // }
    // Debug -- Find Kth If Exist Is Right

    // while(1);//Just Let My Procedure Stop
    return 0;
}

禁止吐槽博主的英文水平

發佈了55 篇原創文章 · 獲贊 15 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章