zoukankan      html  css  js  c++  java
  • bzoj3224Tyvj 1728 普通平衡树 treap

    3224: Tyvj 1728 普通平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 17706  Solved: 7764
    [Submit][Status][Discuss]

    Description

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
    1. 插入x数
    2. 删除x数(若有多个相同的数,因只删除一个)
    3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
    4. 查询排名为x的数
    5. 求x的前驱(前驱定义为小于x,且最大的数)
    6. 求x的后继(后继定义为大于x,且最小的数)

    Input

    第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

    Output

    对于操作3,4,5,6每行输出一个数,表示对应答案

    Sample Input

    10
    1 106465
    4 1
    1 317721
    1 460929
    1 644985
    1 84185
    1 89851
    6 81968
    1 492737
    5 493598

    Sample Output

    106465
    84185
    492737

    HINT

    1.n的数据范围:n<=100000

    2.每个数的数据范围:[-2e9,2e9]

    Source

    平衡树

    题目上没说,但是此题是权值小的排在前面。。因为这个我调了1h
    treap操作
    求前驱后继的时候注意开全局变量而不是函数return,因为函数return 不好写

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #define ll long long
    #define N 100050
    using namespace std;
    int n,rt,cnt,ans;struct node{int l,r,w,siz,val,rd;}t[N];
    void update(int u){t[u].siz=t[t[u].l].siz+t[t[u].r].siz+t[u].w;}
    void lturn(int &u){
        int tmp=t[u].r;t[u].r=t[tmp].l;t[tmp].l=u;
        t[tmp].siz=t[u].siz;update(u);u=tmp;
    }
    void rturn(int &u){
        int tmp=t[u].l;t[u].l=t[tmp].r;t[tmp].r=u;
        t[tmp].siz=t[u].siz;update(u);u=tmp;
    }
    void insert(int &u,int v){
        if(!u){
            u=++cnt;t[u].w=t[u].siz=1;
            t[u].rd=rand();t[u].val=v;
            return;
        }
        t[u].siz++;
        if(v==t[u].val){
            t[u].w++;
            return;
        }
        if(v>t[u].val){
            insert(t[u].r,v);
            if(t[u].rd>t[t[u].r].rd)lturn(u);
        }
        else{
            insert(t[u].l,v);
            if(t[u].rd>t[t[u].l].rd)rturn(u);
        }
    }
    void del(int &u,int x){
        if(!u)return;
        if(t[u].val==x){
            if(t[u].w>1){
                t[u].w--;t[u].siz--;
                return;
            }
            if(t[u].l*t[u].r==0)u=t[u].l+t[u].r;
            else if(t[t[u].l].rd<t[t[u].r].rd)rturn(u),del(u,x);
            else lturn(u),del(u,x);
        }
        else if(x>t[u].val)t[u].siz--,del(t[u].r,x);
        else t[u].siz--,del(t[u].l,x);
    }
    int getrank(int u,int v){
        if(t[u].val==v)return t[t[u].l].siz+1;
        if(t[u].val>v)return getrank(t[u].l,v);
        return t[t[u].l].siz+t[u].w+getrank(t[u].r,v);
    }
    int getval(int u,int x){
        int ls=t[t[u].l].siz;ls=max(ls,0);
        if(x>ls&&x<=ls+t[u].w)return t[u].val;
        if(x<=ls)return getval(t[u].l,x);
        return getval(t[u].r,x-ls-t[u].w);
    }
    void getpre(int u,int x){
        if(!u)return;
        if(t[u].val<x){
            ans=u;
            getpre(t[u].r,x);
        }
        else getpre(t[u].l,x);
    }
    void getsuf(int u,int x){
        if(!u)return;
        if(t[u].val>x){
            ans=u;
            getsuf(t[u].l,x);
        }
        else getsuf(t[u].r,x);
    }
    /*
    debug
    void dfs(int u){
        if(!u)return;
        printf("%d %d %d %d
    ",u,t[u].l,t[u].r,t[u].val);
        dfs(t[u].l);
        dfs(t[u].r);
    }
    */
    int main(){
        scanf("%d",&n);
        int op,x;int m=0;
        while(n--){
            //debug  printf("line:%d 
    ",++m);
            scanf("%d%d",&op,&x);
            if(op==1)insert(rt,x);
            if(op==2)del(rt,x);
            if(op==3)printf("%d
    ",getrank(rt,x));
            if(op==4)printf("%d
    ",getval(rt,x));
            if(op==5)ans=0,getpre(rt,x),printf("%d
    ",t[ans].val);
            if(op==6)ans=0,getsuf(rt,x),printf("%d
    ",t[ans].val);
        }
        return 0;
    }
  • 相关阅读:
    数据库基本操作
    守护线程
    线程使用的场景
    创建多线程
    用正则表达式去截取网页里文字的方法。参数为读取的网页源代码
    文章生成器,Split方法截取字符串。从硬盘读取文件,和向硬盘存储文件参考代码
    winform 阶段学习总结
    Windowform 窗体关联数据库存储,读取图片,参考代码
    windows form窗体应用程序,建一个记事本参考代码,重点是打开,保存,另存为
    js实现相册翻页,滚动,切换,轮播功能
  • 原文地址:https://www.cnblogs.com/wsy01/p/8092569.html
Copyright © 2011-2022 走看看