• poj3481 splaytree模板题


    找不到错在哪里,先留着吧

    /*
    splay是以键值排序的!
    三个操作:1 a b,z增加键值为b的点,值为a
             2,查询最大值
             3,查询最小值
    需要的操作:rotate,splay,insert,findx,delete
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define maxn 1000005
    int pre[maxn],ch[maxn][2],size[maxn],key[maxn],num[maxn],root,tot;
    
    void newnode(int &r,int fa,int k,int val){
        r=++tot;
        pre[r]=fa;
        ch[r][0]=ch[r][1]=0;
        key[r]=k;
        num[r]=val;
    }
    void pushup(int r){
        size[r]=0;
        if(ch[r][0]) size[r]+=size[ch[r][0]];
        if(ch[r][1]) size[r]+=size[ch[r][1]];
        size[r]+=1;
    } 
    void rotate(int x,int kind){//0左旋,1右旋
        int fa=pre[x];
        ch[fa][!kind]=ch[x][kind];
        pre[ch[x][kind]]=fa;
        if(pre[fa])
            ch[pre[fa]][ch[pre[fa]][1]==fa]=x;
        pre[x]=pre[fa];
        pre[fa]=x;
        ch[x][kind]=fa;
        pushup(fa);
        pushup(x);
    }
    void splay(int r,int goal){
        while(pre[r]!=goal){
            if(pre[pre[r]]==goal) rotate(r,ch[pre[r]][0]==r);
            else {
                int fa=pre[r];
                int kind=ch[pre[fa]][0]==fa;//fa的旋转方向,与fa所在子树相反
                if(ch[fa][kind]==r){rotate(r,!kind);rotate(r,kind);}
                else{rotate(fa,kind);rotate(r,kind);}
            }
        }
        if(goal==0) root=r;
        pushup(r);
    }
    void init(){
        root=tot=0;
        ch[root][0]=ch[root][1]=pre[root]=size[root]=num[root]=key[root]=0;
    }
    void insert(int k,int val){//插入键值为k的结点
        int r=root;
        if(r==0) {newnode(root,0,k,val);pushup(root);return;}
        while(ch[r][key[r]<k]) r=ch[r][key[r]<k];
        newnode(ch[r][key[r]<k],r,k,val);
        splay(ch[r][key[r]<k],0);//把k提上去作为根
        pushup(r);
    }
    int getth(int r,int pos){//返回第pos个结点的
        int t=size[ch[r][0]]+1;
        if(pos==t) return r;
        else if(pos<t) getth(ch[r][0],pos);
        else getth(ch[r][1],pos-t);
    }
    void remove(){//删除根节点
        if(ch[root][0]==0){root=ch[root][1];pre[root]=0;}//只有右子树
        else {
            int tmp=getth(ch[root][0],size[ch[root][0]]);
            splay(tmp,root);
            ch[tmp][1]=ch[root][1];
            pre[ch[root][1]]=tmp;
            root=tmp;
            pre[root]=0;
        }
        pushup(root);
    }
    int main(){
        int op,k,p;
        init();//建立一颗空树
        while(scanf("%d",&op)&&op){
            if(op==2){//最大值
                if(root==0) {
                    puts("0");
                    continue;
                }
                int ans=getth(root,size[root]);
                splay(ans,0);
                printf("%d
    ",num[ans]);
                remove();
                //debug();
            }
            else if(op==3){
                if(root==0){
                    puts("0");
                    continue;
                }
                int ans=getth(root,1);
                splay(ans,0);
                printf("%d
    ",num[ans]);
                remove();
                //debug();
            }
            else {
                scanf("%d%d",&k,&p);
                insert(p,k);//p是关键字,k是值
                //debug();
            }
        }
        return 0;
    }

     终于过了:和上面做法有些不同,找到最大或最小的点,将其作为根,同时将前驱后缀提取出来当做子树

    /*
    
    */
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define maxn 100005
    #define inf 0x3f3f3f3f
    int pre[maxn],ch[maxn][2],nums[maxn],keys[maxn],size[maxn],tot,root;
    
    inline void newnode(int &r,int fa,int k,int val){
        r=++tot;
        ch[r][0]=ch[r][1]=0;
        pre[r]=fa;
        size[r]=1;
        nums[r]=val;
        keys[r]=k;
    }
    void init(){
        tot=root=0;
        pre[root]=ch[root][0]=ch[root][1]=size[root]=0;
    }
    inline void pushup(int x){
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
    }    
    inline void rotate(int x,int kind){
        int fa=pre[x];
        ch[fa][!kind]=ch[x][kind];
        pre[ch[x][kind]]=fa;
        pre[x]=pre[fa];
        if(pre[fa])
            ch[pre[fa]][ch[pre[fa]][1]==fa]=x;
        ch[x][kind]=fa;
        pre[fa]=x;
        pushup(fa);
        pushup(x);
    }
    inline void splay(int x,int goal){
        while(pre[x]!=goal){
            if(pre[pre[x]]==goal) rotate(x,ch[pre[x]][0]==x);
            else {
                int fa=pre[x];
                int kind=ch[pre[fa]][0]==fa;
                if(ch[fa][kind]==x){
                    rotate(x,!kind);
                    rotate(x,kind);
                }
                else {
                    rotate(fa,kind);
                    rotate(x,kind);
                }
            }
        }
        pushup(x);
        if(goal==0) root=x;
    }
    int find(int key){
        if(root==0) return 0;
        int x=root;
        while(x && keys[x]!=key)
            x=ch[x][key>keys[x]];
        if(x) splay(x,0);
        return x;
    }
    int prev(){
        int x=ch[root][0];
        if(x==0) return 0;//ÎÞÇ°Çý
        while(ch[x][1])
            x=ch[x][1];
        return x; 
    }
    int succ(){
        int x=ch[root][1];
        if(x==0) return 0;//ÎÞºó¼Ì
        while(ch[x][0])
            x=ch[x][0];
        return x; 
    }
    void insert(int key,int num){
        if(root==0) {newnode(root,0,key,num);return;}
        int x=root,lastx=0;
        while(x){
            lastx=x;
            x=ch[x][key>keys[x]];
        }
        newnode(x,lastx,key,num);
        ch[lastx][key>keys[lastx]]=x;
        pre[x]=lastx;
        splay(x,0);
    }
    
    void del(int key){
        int x=find(key);
        if(x==0) return;    
        int tmp1=prev(),tmp2=succ();
        if(!tmp1 && !tmp2){root=0;return;}
        if(!tmp1){//Ö»ÓÐÓÒ×ÓÊ÷ 
            splay(tmp2,0);
            ch[tmp2][0]=0;
            pushup(tmp2);
            return;
        }
        if(!tmp2){//Ö»ÓÐ×ó×ÓÊ÷ 
            splay(tmp1,0);
            ch[tmp1][1]=0;
            pushup(tmp1);
            return;
        }
        splay(tmp1,0);
        splay(tmp2,tmp1);
        ch[tmp2][0]=0; 
        pushup(tmp2);pushup(tmp1);
    }
    int getth(int x,int pos){
        if(root==0) return 0;
        int t=size[ch[x][0]]+1;
        if(pos==t) return x;
        else if(pos<t) return getth(ch[x][0],pos);
        else return getth(ch[x][1],pos-t);
    }
    int main(){        
        int p,key,num,x;
        while(scanf("%d",&p)&&p){
            switch(p){    
                case 1:
                    scanf("%d%d",&num,&key);
                    insert(key,num);
                    break;
                case 2:    
                    x=getth(root,size[root]);
                    if(x){
                        printf("%d
    ",nums[x]);
                        del(keys[x]);
                    }    
                    else printf("0
    ");
                    break;
                case 3:
                    x=getth(root,1);
                    if(x){
                        printf("%d
    ",nums[x]);
                        del(keys[x]);
                    }
                    else printf("0
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    HIVE中内连接和左半连接不一致问题
    hive 中的Sort By、 Order By、Cluster By、Distribute By 区别
    基于MapReduce的矩阵乘法运算
    基于MapReduce的关系代数运算(2)
    基于MapReduce的关系代数运算(1)
    帖子爬取
    tomcat------https单向认证和双向认证
    struts2配置文件struts.xml的简介
    2014,事情只有一件!
    MYSQLi数据访问查询数据
  • 原文地址:https://www.cnblogs.com/zsben991126/p/9992390.html
Copyright © 2020-2023  润新知