码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj3224Tyvj 1728 普通平衡树 treap

时间:2017-12-23 11:52:57      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:string   class   gpo   otto   page   pac   mem   oid   blog   

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\n",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 \n",++m);
        scanf("%d%d",&op,&x);
        if(op==1)insert(rt,x);
        if(op==2)del(rt,x);
        if(op==3)printf("%d\n",getrank(rt,x));
        if(op==4)printf("%d\n",getval(rt,x));
        if(op==5)ans=0,getpre(rt,x),printf("%d\n",t[ans].val);
        if(op==6)ans=0,getsuf(rt,x),printf("%d\n",t[ans].val);
    }
    return 0;
}

bzoj3224Tyvj 1728 普通平衡树 treap

标签:string   class   gpo   otto   page   pac   mem   oid   blog   

原文地址:http://www.cnblogs.com/wsy01/p/8092569.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!