您的位置:首页 > 其它

POJ 1442 平衡树Treap模板

2017-03-01 16:28 399 查看
点击打开链接

题意:输入m个数,询问n个数,第一个数如果是3,就输出在m的第三个数输入完成后第1大的数,第二个就输出第二大的数,但前提都是在输入完U[i]个数后

思路:用平衡树Treap进行插入和查询第K大的数,模版题

[html] view
plain copy

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

}  

[html] view
plain copy

#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
14c77
==-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;  

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  treap