题目:http://www.spoj.com/problems/ORDERSET/

题意:给定n个操作,I,D,K,C,分别代表插入,删除,找第K大元素,找小于x的元素个数。

分析:这里插入,删除和找第K大元素很简单,直接就是模版,但是这里找小于x的元素个数不好处理。

因为Rank(Treap *t,int x)返回的是元素x在Treap中的排名,所以这里要求x在Treap一定是存在的,但是找小于x的元素个

数,这里的x不一定在Treap中。

后来我想到了一个方法,就是在查找之前,我们先查找x在Treap中是否存在,如果存在,就不用管了。

答案就是Rank(root,x)-1,否则,我们就应该先插入x,然后执行Rank(root,x)-1,再删除x,这样耗时明显增多,不过还是

能过。

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
struct Treap
{
int size;
int key,fix;
Treap *ch[2];
Treap(int key)
{
size=1;
fix=rand();
this->key=key;
ch[0]=ch[1]=NULL;
}
int compare(int x) const
{
if(x==key) return -1;
return x<key? 0:1;
}
void Maintain()
{
size=1;
if(ch[0]!=NULL) size+=ch[0]->size;
if(ch[1]!=NULL) size+=ch[1]->size;
}
};
void Rotate(Treap* &t,int d)
{
Treap *k=t->ch[d^1];
t->ch[d^1]=k->ch[d];
k->ch[d]=t;
t->Maintain();  //必须先维护t,再维护k,因为此时t是k的子节点
k->Maintain();
t=k;
}
void Insert(Treap* &t,int x)
{
if(t==NULL) t=new Treap(x);
else
{
//int d=t->compare(x);   //如果值相等的元素只插入一个
int d=x < t->key ? 0:1;  //如果值相等的元素都插入
Insert(t->ch[d],x);
if(t->ch[d]->fix > t->fix)
Rotate(t,d^1);
}
t->Maintain();
}
//一般来说,在调用删除函数之前要先用Find()函数判断该元素是否存在
void Delete(Treap* &t,int x)
{
int d=t->compare(x);
if(d==-1)
{
Treap *tmp=t;
if(t->ch[0]==NULL)
{
t=t->ch[1];
delete tmp;
tmp=NULL;
}
else if(t->ch[1]==NULL)
{
t=t->ch[0];
delete tmp;
tmp=NULL;
}
else
{
int k=t->ch[0]->fix > t->ch[1]->fix ? 1:0;
Rotate(t,k);
Delete(t->ch[k],x);
}
}
else Delete(t->ch[d],x);
if(t!=NULL) t->Maintain();
}
bool Find(Treap *t,int x)
{
while(t!=NULL)
{
int d=t->compare(x);
if(d==-1) return true;
t=t->ch[d];
}
return false;
}
int Kth(Treap *t,int k)
{
if(t==NULL||k<=0||k>t->size)
return -1;
if(t->ch[0]==NULL&&k==1)
return t->key;
if(t->ch[0]==NULL)
return Kth(t->ch[1],k-1);
if(t->ch[0]->size>=k)
return Kth(t->ch[0],k);
if(t->ch[0]->size+1==k)
return t->key;
return Kth(t->ch[1],k-1-t->ch[0]->size);
}
int Rank(Treap *t,int x)
{
int r;
if(t->ch[0]==NULL) r=0;
else  r=t->ch[0]->size;
if(x==t->key) return r+1;
if(x<t->key)
return Rank(t->ch[0],x);
return r+1+Rank(t->ch[1],x);
}
int Depth(Treap *t)
{
if(t==NULL) return -1;
int l=Depth(t->ch[0]);
int r=Depth(t->ch[1]);
return l<r ? (r+1):(l+1);
}
void DeleteTreap(Treap* &t)
{
if(t==NULL) return;
if(t->ch[0]!=NULL) DeleteTreap(t->ch[0]);
if(t->ch[1]!=NULL) DeleteTreap(t->ch[1]);
delete t;
t=NULL;
}
void Print(Treap *t)
{
if(t==NULL) return;
Print(t->ch[0]);
cout<<t->key<<endl;
Print(t->ch[1]);
}
int main()
{
int n,x;
char str[5];
scanf("%d",&n);
Treap *root=NULL;
while(n--)
{
scanf("%s%d",str,&x);
if(str[0]=='I')
{
if(!Find(root,x))
Insert(root,x);
}
else if(str[0]=='D')
{
if(Find(root,x))
Delete(root,x);
}
else if(str[0]=='K')
{
int tmp=Kth(root,x);
if(tmp==-1) puts("invalid");
else        printf("%d\n",tmp);
}
else
{
bool flag=1;
if(!Find(root,x))
Insert(root,x);
else
flag=0;
printf("%d\n",Rank(root,x)-1);
if(flag)
Delete(root,x);
}
}
DeleteTreap(root);
return 0;
}

SPOJ3273(Treap)相关推荐

  1. 【Treap】bzoj1588-HNOI2002营业额统计

    一.题目 Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司 ...

  2. 【bzoj2770】YY的Treap 权值线段树

    题目描述 志向远大的YY小朋友在学完快速排序之后决定学习平衡树,左思右想再加上SY的教唆,YY决定学习Treap.友爱教教父SY如砍瓜切菜般教会了YY小朋友Treap(一种平衡树,通过对每个节点随机分 ...

  3. 2019 ICPC 南昌 K. Tree(树上启发式合并,平衡树 treap)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://nanti.jisuanke.com/t/42586 Problem 给定一 ...

  4. luogu P2596 [ZJOI2006]书架(平衡树、无旋treap(按排名分裂)一些更复杂的操作)

    P2596 [ZJOI2006]书架 无旋treap可以维护一棵树的中序遍历结果.但是不支持通过编号来找节点.于是在无旋treap的基础上,我维护了每个节点的父亲,这样就可以求出一个节点是中序遍历中的 ...

  5. luogu P3391 【模板】文艺平衡树(FHQ - treap,懒惰标记)

    整理的算法模板合集: ACM模板 我们把每个查询区间使用solit分裂成[1l−1][lr][r+1n][1~l-1][l~r][r+1~n][1 l−1][l r][r+1 n]三个区间. 再把[l ...

  6. 模板 - FHQ - treap 无旋平衡树

    整理的算法模板合集: ACM模板 目录 FQH - treap 无旋平衡树 按权值分裂 按排名分裂 文艺平衡树 可持久化序列 FQH - treap 无旋平衡树 operator 1 : 插入一个数 ...

  7. 【数据结构】平衡树 - treap

    treap = tree + heap 树堆(treap:让BST尽量随机) 动态维护一个有序序列 对于一个大根堆: 最大值:一直往右走 最小值:一直往左走 treap实现操作 set实现 ①插入 i ...

  8. BZOJ1112[POI2008]砖块Klo——非旋转treap

    题目描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任 ...

  9. 三大平衡树(Treap + Splay + SBT)总结+模板

    Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...

最新文章

  1. 小波变换和小波包变换
  2. 动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
  3. 组建Livebos超级快速开发平台学习研讨QQ群 !
  4. 客户端不支持javascript怎么办
  5. Spark和机器学习整合
  6. vue-cli搭建项目(笔记)
  7. [比赛]2015/12/25BNU新生赛
  8. linux(Centos7系统)中安装JDK、Tomcat、Mysql
  9. 三个杯子的倒水问题(BFS)
  10. 基于Matpower的电力系统潮流计算仿真
  11. Matlab里面如何实现多行注释
  12. 十六进制格式颜色转换成RGB格式颜色
  13. cityscape train.txt 数据 python读取子文件夹内所有文件
  14. java-opencv 米粒数_Python opencv学习音符的米粒数,返回每个米粒的位置面积和总米粒数的平均面积,pythonopencv,笔记,之数,并,一个,及,个数...
  15. 快速:通过画图了解Racket
  16. 计算机专业可以从事平面设计吗,计算机专业和平面设计专业是一个专业不?
  17. A callback was made on a garbage collected delegate of type...
  18. 被玩坏的IE浏览器——漏洞利用方法和技巧介绍
  19. 数据库设计讲解和案例分析 | mysql 入门
  20. 解决python安装依赖包出现 Microsoft Visual C++ 14.0 or greater is required问题

热门文章

  1. Spring-Cloud中常见的服务组件
  2. 使用注解配置声明式事务控制
  3. 上传问题分析--目录分离
  4. RocketMQ的历史发展
  5. 数据库-优化-pt-kill-授权-数据
  6. 入门案例中使用的组件介绍
  7. 使用传统的方式,遍历集合,对集合中的数据进行过滤
  8. 函数的参数-在函数内部使用方法修改可变参数会影响外部实参
  9. MYBATIS 批量update 报错的问题
  10. SpringBoot_web开发-扩展与全面接管SpringMVC