题目描述

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

  1. 插入x数
  2. 删除x数(若有多个相同的数,因只删除一个)
  3. 查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
  4. 查询排名为x的数
  5. 求x的前驱(前驱定义为小于x,且最大的数)
  6. 求x的后继(后继定义为大于x,且最小的数)

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例:


输出样例:



Splay 解析尚未完成 参见yyb dalao的博客

丑陋的代码送上(yyb大佬的代码比我的漂亮多了):

#ifndef SPLAY_TREE_HPP
#define SPLAY_TREE_HPP
#include<bits/stdc++.h>
using namespace std;
namespace Splay_tree
{
template<typename T>
struct splay_node
{
T value;
int size;
int cnt;
bool reverse;
splay_node *father;
splay_node *son[];
splay_node(){}
splay_node(T v, splay_node *f=NULL)
:value(v),cnt()
{
father=f;
size=;
son[]=son[]=NULL;
}
}; template<typename T, typename C=less<T> >
class Splay
{
private:
typedef splay_node<T> node;
node *root;
C small_to;
bool big_to(T x, T y){return small_to(y,x);}
bool equal_to(T x, T y){return !(small_to(x,y)||big_to(x,y));} inline bool son(node *f, node *s)
{
return f->son[]==s;
}
inline void rotate(node *t)
{
node *f = t->father;
node *g = f->father;
bool a = son(f, t), b = !a;
f->son[a] = t->son[b];
if (t->son[b] != NULL)
t->son[b]->father = f;
t->son[b] = f;
f->father = t;
t->father = g;
if (g != NULL)
g->son[son(g, f)] = t;
else
root = t;
update(f);
update(t);
} inline void splay(node *t, node *p)
{
while (t->father != p)
{
node *f = t->father;
node *g = f->father;
if (g == p)
rotate(t);
else
{
if (son(g, f) ^ son(f, t)) rotate(t), rotate(t);
else rotate(f), rotate(t);
}
}
update(t);
} inline T k_th(int k, node *f)
{
int tmp;
node *t=root;
while()
{
int tmp=size(t->son[])+t->cnt;
int sze=tmp-t->cnt;
if(k<=tmp&&sze<k) break;
else if(k<=sze) t=t->son[];
else k-=tmp,t=t->son[];
}
T ans=t->value;
return ans;
} inline node* insert(T val, node *t)
{
int b=big_to(val,t->value);
if(equal_to(val,t->value))
{
t->cnt++;
update(t);
return t;
}
if(t->son[b]==NULL)
{
t->son[b]=new node(val,t);
update(t->son[b]);
update(t);
return t->son[b];
}
else
{
node *ans=insert(val,t->son[b]);
update(t);
return ans;
}
} public:
Splay()
{
root=NULL;
} inline void insert(T val)
{
if (root == NULL)
{
root = new node(val, NULL);
update(root);
return;
}
else
{
node *t = insert(val,root);
splay(t,NULL);
}
} inline void erase(T val)
{
node *t = root;
while(t)
{
if (equal_to(t->value,val))
break;
t = t->son[big_to(val,t->value)];
}
if (t != NULL)
{
splay(t, NULL);
if(t->cnt>)
{
t->cnt--;
update(t);
return;
}
if (t->son[] == NULL)
{
root = t->son[];
if (root != NULL)
{
root->father = NULL;
update(root);
}
}
else
{
node *p = t->son[];
while (p->son[] != NULL)
p = p->son[];
splay(p, t); root = p;
root->father = NULL;
p->son[] = t->son[];
update(p);
if (p->son[] != NULL)
p->son[]->father = p;
}
}
} inline T pre(T val)
{
T ans=pre_ptr(val)->value;
return ans;
} inline T suc(T val)
{
node *x = root;
insert(val);
node *t=root->son[];
if(t==NULL) return T(NULL);
while(t->son[]!=NULL) t=t->son[];
erase(val);
T ans=t->value;
return ans;
} inline T max_value()
{
node *t=root;
while(t->son[]!=NULL) t=t->son[];
return t->value;
} inline T min_value()
{
node *t=root;
while(t->son[]!=NULL) t=t->son[];
return t->value;
} inline T k_th(int k)
{
return k_th(k,NULL);
} inline int rank(T val)
{
node *t=root;
while(!equal_to(t->value, val))
t=t->son[big_to(val,t->value)];
splay(t,NULL);
return size(t->son[])+;
} inline void print()
{
print(root);
puts("");
} private: inline node* pre_ptr(T val)
{
insert(val);
node *t=root->son[];
if(t==NULL) return NULL;
while(t->son[]!=NULL) t=t->son[];
erase(val);
return t;
} inline void print(node *t)
{
if(t==NULL) return;
print(t->son[]);
printf("%d ",t->value);
print(t->son[]);
} inline int size(node *t)
{
return t == NULL ? : t->size;
} inline void update(node *t)
{
t->size = t->cnt;
t->size += size(t->son[]);
t->size += size(t->son[]);
}
};
}
#endif int main()
{
using namespace Splay_tree;
int n;
Splay<int> tree;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
int ops;
int x;
scanf("%d%d",&ops,&x);
switch(ops)
{
case :
tree.insert(x);
break;
case :
tree.erase(x);
break;
case :
{
int t=tree.rank(x);
printf("%d\n",t);
break;
}
case :
{
int y=tree.k_th(x);
printf("%d\n",y);
break;
}
case :
printf("%d\n",tree.pre(x));
break;
case :
int t=tree.suc(x);
printf("%d\n",t);
break;
}
}
}

洛谷 P3369 【模板】普通平衡树(Treap/SBT)的更多相关文章

  1. luoguP3369[模板]普通平衡树(Treap/SBT) 题解

    链接一下题目:luoguP3369[模板]普通平衡树(Treap/SBT) 平衡树解析 #include<iostream> #include<cstdlib> #includ ...

  2. 洛谷.3369.[模板]普通平衡树(fhq Treap)

    题目链接 第一次(2017.12.24): #include<cstdio> #include<cctype> #include<algorithm> //#def ...

  3. 【洛谷P3369】普通平衡树——Splay学习笔记(一)

    二叉搜索树(二叉排序树) 概念:一棵树,若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 它的左.右子树也分别为二叉搜索树 ...

  4. 洛谷.3369.[模板]普通平衡树(Splay)

    题目链接 第一次写(2017.11.7): #include<cstdio> #include<cctype> using namespace std; const int N ...

  5. 洛谷.3391.[模板]文艺平衡树(Splay)

    题目链接 //注意建树 #include<cstdio> #include<algorithm> const int N=1e5+5; //using std::swap; i ...

  6. 洛谷P3369 【模板】普通平衡树(Treap/SBT)

    洛谷P3369 [模板]普通平衡树(Treap/SBT) 平衡树,一种其妙的数据结构 题目传送门 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除 ...

  7. 【洛谷P3369】【模板】普通平衡树题解

    [洛谷P3369][模板]普通平衡树题解 题目链接 题意: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3 ...

  8. 洛谷P3369普通平衡树(Treap)

    题目传送门 转载自https://www.cnblogs.com/fengzhiyuan/articles/7994428.html,转载请注明出处 Treap 简介 Treap 是一种二叉查找树.它 ...

  9. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  10. AC日记——【模板】普通平衡树(Treap/SBT) 洛谷 P3369

    [模板]普通平衡树(Treap/SBT) 思路: 劳资敲了一个多星期: 劳资终于a了: 劳资一直不a是因为一个小错误: 劳资最后看的模板: 劳资现在很愤怒: 劳资不想谈思路!!! 来,上代码: #in ...

随机推荐

  1. jq实现多级菜单

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  2. node.js的npm命令常见错误及解决方案

    使用npm命令进行模块安装的时候场出现各种错误,本文总结我所遇到的各种错误,并提供解决方案.(大部分内容为网上收集) 首先使用淘宝 NPM 镜像 大家都知道国内直接使用 npm 的官方镜像是非常慢的, ...

  3. Linux 启动进程结束进程通用代码

    linux启动springboot项目 start.sh #!/bin/sh rm -f tpid nohup java -jar restDate--SNAPSHOT.jar --spring.pr ...

  4. ASP.NET Core AD 域登录 (转载)

    在选择AD登录时,其实可以直接选择 Windows 授权,不过因为有些网站需要的是LDAP获取信息进行授权,而非直接依赖Web Server自带的Windows 授权功能. 当然如果使用的是Azure ...

  5. CORS support for ASP.NET Web API (转载)

    CORS support for ASP.NET Web API Overview Cross-origin resource sharing (CORS) is a standard that al ...

  6. first-child伪类选择器

    原文链接地址:https://www.cnblogs.com/wangmeijian/p/4562304.html :first-child 选择器用于选取属于其父元素的首个子元素的指定选择器.——w ...

  7. 获取 iOS APP 内存占用的大小

    当我们想去获取 iOS 应用的占用内存时,通常我们能找到的方法是这样的,用 resident_size:   #import <mach/mach.h> - (int64_t)memory ...

  8. http协议的总结

    HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统,其主要特点概括如下: 1.支持客户/服务器模式. 2.简单快速:客户向服务器请求服务时,只需传送请求方法和 ...

  9. CentOS6安装各种大数据软件 第九章:Hue大数据可视化工具安装和配置

    相关文章链接 CentOS6安装各种大数据软件 第一章:各个软件版本介绍 CentOS6安装各种大数据软件 第二章:Linux各个软件启动命令 CentOS6安装各种大数据软件 第三章:Linux基础 ...

  10. C# 删除指定目录下的所有文件及文件夹

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Tex ...