bzoj3224

学习了下treap

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int inf=1<<29;
int n,mn,root,delta,tot,ans;
int size[100010],child[100010][2],cnt[100010],key[100010],p[100010];
void update(int x)
{
    size[x]=size[child[x][0]]+size[child[x][1]]+cnt[x];
}
void rotate(int&x,int t)
{
    int y=child[x][t];
    child[x][t]=child[y][1-t];
    child[y][1-t]=x;
    update(x);
    update(y);
    x=y;
}
void insert(int&x,int k)
{
    if(x)
    {
        if(key[x]==k) cnt[x]++;
        else
        {
            int t=key[x]<k;
            insert(child[x][t],k);
            if(p[x]<p[child[x][t]]) rotate(x,t);
        }
    }
    else
    {
        ++tot;
        x=tot;
        p[x]=rand();
//      printf("%d\n",p[x]);
        key[x]=k;
        cnt[x]=1;
    }
    update(x);
}
void erase(int&x,int k)
{
    if(key[x]==k)
    {
        if(cnt[x]>1)
        {
            cnt[x]--;
            update(x);
            return;
        }
        if(!child[x][0]&&!child[x][1])
        {
            x=0;
            return;
        }
        int t=p[child[x][1]]>p[child[x][0]];
        rotate(x,t);
        erase(child[x][t^1],k);
    } else erase(child[x][key[x]<k],k);
    update(x);
}
int find(int x,int k)
{
    if(k<=size[child[x][0]])
        return find(child[x][0],k);
    k-=size[child[x][0]]+cnt[x];
    if(k<=0) return key[x];
    return find(child[x][1],k);
}
int findrank(int x,int k)
{
    if(key[x]==k) return size[child[x][0]]+1;
    if(key[x]<k) return findrank(child[x][1],k)+cnt[x]+size[child[x][0]];
    if(key[x]>k) return findrank(child[x][0],k);
}
void findpro(int x,int k)
{
    if(x==0) return;
    if(key[x]<k)
    {
        ans=key[x];
        findpro(child[x][1],k);
    } else findpro(child[x][0],k);
}
void findnxt(int x,int k)
{
    if(x==0) return;
    if(key[x]>k)
    {
        ans=key[x];
        findnxt(child[x][0],k);
    } else findnxt(child[x][1],k);
}
int main()
{
    p[0]=-inf;
    scanf("%d",&n);
    while(n--)
    {
        int opt,a; scanf("%d%d",&opt,&a);
//      printf("----------\nopt=%d\n",opt);
        if(opt==1) insert(root,a);
        if(opt==2) erase(root,a);
        if(opt==3) printf("%d\n",findrank(root,a));
        if(opt==4) printf("%d\n",find(root,a));
        if(opt==5) {findpro(root,a);printf("%d\n",ans);ans=0;}
        if(opt==6) {findnxt(root,a);printf("%d\n",ans);ans=0;}
//      printf("----------\n");
    }
    return 0;
}
时间: 2025-01-05 20:48:00

bzoj3224的相关文章

【bzoj3224】 Tyvj1728—普通平衡树

http://www.lydsy.com/JudgeOnline/problem.php?id=3224 (题目链接) 题意 1. 插入x数:2. 删除x数(若有多个相同的数,因只删除一个):3. 查询x数的排名(若有多个相同的数,因输出最小的排名):4. 查询排名为x的数:5. 求x的前驱(前驱定义为小于x,且最大的数):6. 求x的后继(后继定义为大于x,且最小的数) Solution treap板子.右转光勋总结→_→:平衡树 细节 一个节点还统计了这个数出现了几次,然后询问排名前驱后继什

【权值线段树】bzoj3224 Tyvj 1728 普通平衡树

一个板子. #include<cstdio> #include<algorithm> using namespace std; #define N 100001 struct Data { int v,p; }t[N]; bool cmp(const Data &a,const Data &b) { return a.v<b.v; } int T[N<<2],op[N],a[N],n,ma[N],e; void Update(int p,int v

[BZOJ3224]普通平衡树(旋转treap)

3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 20328  Solved: 8979[Submit][Status][Discuss] Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. 求x的前驱(前驱定义为

bzoj3224 Tyvj 1728 普通平衡树

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,

【bzoj3224】Tyvj 1728 普通平衡树 平衡树的三种姿势 :splay,Treap,ScapeGoat_Tree

直接上代码 正所谓 人傻自带大常数 平衡树的几种姿势:  AVL Red&Black_Tree 码量爆炸,不常用:SBT 出于各种原因,不常用. 常用: Treap 旋转 基于旋转操作和随机数堆 但不支持区间操作. 非旋转 基于随机数堆和拆分合并操作 常数较大 Spaly 完全基于旋转 各种操作 ScapeGoat_Tree 基于a权值平衡树和压扁重构 无旋转 但不支持区间操作 PS:非旋转可以实现平衡树的可持久化,从而来套一些东西 splay #include<cstdio> #de

bzoj3224 普通平衡树(splay 模板)

3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 11427  Solved: 4878[Submit][Status][Discuss] Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. 求x的前驱(前驱定义为

bzoj3224 普通平衡树

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每行输

【bzoj3224】普通平衡树——treap

我的第一道treap题目,treap的模版题. 代码是对着hzw的敲的,一边敲一边理解... 主要是熟悉一下treap的各种基本操作,详细细节看代码. #include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> using namespace std; struct point { int l,r,v,rnd,size,w; }tree[100005]; int n,size

bzoj3224: Tyvj 1728 普通平衡树(打个splay暖暖手)

(其实今天好热啊? 题目大意:插入,删除,k小,前驱后继,数的排名. splay和treap裸题...过几天补个treap的 splay: #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> using namespace std; const int extar[3]={0,2147483647,-2147483647}; int fa[100010],count[

BZOJ3224: Tyvj 1728 普通平衡树[treap]

3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 9046  Solved: 3840[Submit][Status][Discuss] Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. 求x的前驱(前驱定义为小