题目描述

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

  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. 以太网,IP,TCP,UDP数据包分析

    http://www.cnblogs.com/feitian629/archive/2012/11/16/2774065.html 网络层的IP 协议是构成Internet 的基础.IP 协议不保证传 ...

  2. 【LeetCode每天一题】Remove Duplicates from Sorted Array II(移除有序数组中重复的两次以上的数字)

    Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twic ...

  3. Unicode data in a Unicode-only collation or ntext data cannot be sent to clients using DB-Library (such as ISQL) or ODBC version 3.7 or earlier

    php 连接 sqlserver 时, 程序生成的sql语句, 如果在 sqlserver客户端执行时, 可以正确返回结果, 在程序中执行, 总返回 false, 打开调试也没有任何错误. 无意中发现 ...

  4. 7、RabbitMQ-主题模式

    1.模式图 发送到主题交换的消息不能具有任意的 routing_key - 它必须是由点分隔的单词列表. 单词可以是任何内容,但通常它们指定与消息相关的一些功能.一些有效的路由键示例:“ stock. ...

  5. PHPStorm自定义主题配置

    1.下载喜欢的主题 官方下载地址:下载 2.将.icls主题文件放到PHPStorm的配置中 windows下主题位置:C:\Users\Administrator\.PhpStorm2017.3\c ...

  6. Unity3D-射线效果

    基于airplane_02 下面新建 Line Renderer 将上面的几个地方设置下 添加Script脚本: 脚本代码为: using System.Collections; using Syst ...

  7. PAT——1048. 数字加密

    本题要求实现一种数字加密方法.首先固定一个加密用正整数A,对任一正整数B,将其每1位数字与A的对应位置上的数字进行以下运算:对奇数位,对应位的数字相加后对13取余——这里用J代表10.Q代表11.K代 ...

  8. PAT——1040. 有几个PAT

    字符串APPAPT中包含了两个单词“PAT”,其中第一个PAT是第2位(P),第4位(A),第6位(T):第二个PAT是第3位(P),第4位(A),第6位(T). 现给定字符串,问一共可以形成多少个P ...

  9. Linux mysql 5.5.10 二进制安装过程记录和 修改 密码 登录

    1.useradd clouder2.解压缩mysql.tar.bz2到/home/clouder2.mv /etc/my.cnf /etc/my.cnf.bak3./home/clouder/mys ...

  10. TXT文件转换成DataSet数据集

    /// <summary> /// TXT文件转换成DataSet数据集 /// </summary> /// <param name="FilePath&qu ...