题目链接:

https://www.lydsy.com/JudgeOnline/problem.php?id=3224

题目大意:

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

思路:

splay:http://www.cnblogs.com/BCOI/p/9010229.html

treap:https://www.cnblogs.com/BCOI/p/9072444.html

 #include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);//不可再使用scanf printf
#define Max(a, b) ((a) > (b) ? (a) : (b))//禁用于函数,会超时
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Mem(a) memset(a, 0, sizeof(a))
#define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1))
#define MID(l, r) ((l) + ((r) - (l)) / 2)
#define lson ((o)<<1)
#define rson ((o)<<1|1)
#pragma comment(linker, "/STACK:102400000,102400000")//栈外挂
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
} typedef long long ll;
const int maxn = + ;
const int MOD = ;//const引用更快,宏定义也更快
const int INF = 1e9 + ;
const double eps = 1e-; struct node
{
int fa;//记录父节点
int ch[];//ch[0]表示左儿子 ch[1]表示右儿子
int val;//节点权值
int Size;//记录节点子树大小(包括该节点)
int cnt;//记录同样权值的元素个数
int mark;//记录反转区间标记(普通平衡树不用)
}t[maxn];
int root = ;//根节点
int cnt = ;//当前节点数目
bool get(int x)//判断一个节点是左节点还是右节点
{
return t[t[x].fa].ch[] == x;//右节点返回1 左节点返回0
}
void up(int x)//重新统计节点x的size
{
t[x].Size = t[t[x].ch[]].Size + t[t[x].ch[]].Size + t[x].cnt;
}
void Rotate(int x)//节点x与父节点旋转
{
int fa = t[x].fa, gfa = t[fa].fa;
int d1 = get(x), d2 = get(fa);//加上d1 d2均表示左儿子
t[fa].ch[d1] = t[x].ch[d1 ^ ]; t[t[x].ch[d1 ^ ]].fa = fa;//父节点的左儿子设置成左儿子的右儿子(双向设置)
t[gfa].ch[d2] = x; t[x].fa = gfa;//祖父节点的左儿子设置成父节点的左儿子(双向)
t[fa].fa = x; t[x].ch[d1^] = fa;//左儿子的右儿子设置成父节点(双向)
up(fa); up(x);
}
void splay(int x, int goal)//x旋转到goal下面
{
while(t[x].fa != goal)
{
int fa = t[x].fa, gfa = t[fa].fa;
int d1 = get(x), d2 = get(fa);
if(gfa != goal)
{
if(d1 == d2)Rotate(fa);//同侧,先旋父节点(双旋)
else Rotate(x);//异侧 直接选
}
Rotate(x);//再向上旋一次
}
if(goal == )root = x;
}
void Insert(int val)
{
int node = root, fa = ;
while(node && t[node].val != val)
fa = node, node = t[node].ch[t[node].val < val];
if(node)t[node].cnt++;//节点存在
else
{
node = ++cnt;
if(fa)t[fa].ch[t[fa].val < val] = node;
t[node].fa = fa;
t[node].Size = t[node].cnt = ;
t[node].val = val;
}
splay(node, );//将新节点旋到根来维护splay的子树
}
int kth(int k)//查询第k大的数
{
int node = root;
while()
{
int son = t[node].ch[];
if(k <= t[son].Size)node = son;
else if(k > t[son].Size + t[node].cnt)
{
k -= t[son].Size + t[node].cnt;
node = t[node].ch[];
}
else return t[node].val;
}
}
int Find(int val)//直接调用Find(INF)或者调用Find(-INF)可以得到最大值和最小值编号
{
int node = root;
while(t[node].val != val && t[node].ch[t[node].val < val])
node = t[node].ch[t[node].val < val];
return node;
}
int get_rank(int val)//查询一个数的排名
{
splay(Find(val), );
return t[t[root].ch[]].Size + ;
}
int get_pre(int val, int kind)//kind = 0 查询前驱 kind = 1查询后继
{
splay(Find(val), );
int node = root;
if(t[node].val < val && kind == )return node;
if(t[node].val > val && kind == )return node;//根节点就是前驱/后继的情况
node = t[node].ch[kind];
while(t[node].ch[kind ^ ])node = t[node].ch[kind ^ ];//否则在子树中寻找最值
return node;//返回的是编号 具体的值调用需要用t[node].val
}
void delet(int val)
{
int last = get_pre(val, );//由于此处查询了前驱和后缀 可能会查询到最小值的前驱或者最大值的后缀
int next = get_pre(val, );//必须事先加入INF 和-INF 不然会出错
splay(last, );
splay(next, last);
if(t[t[next].ch[]].cnt > )
{
t[t[next].ch[]].cnt--;
splay(t[next].ch[], );
}
else t[next].ch[] = ;
}
int main()
{
int n, x, y;
Insert(-INF);
Insert(INF);
scanf("%d", &n);
while(n--)
{
scanf("%d%d", &x, &y);
if(x == )Insert(y);
if(x == )delet(y);
if(x == )printf("%d\n", get_rank(y)- );//排名减一是因为要减去负无穷这个数
if(x == )printf("%d\n", kth(y + ));//排名是y+1 因为加上负无穷这个数
if(x == )printf("%d\n", t[get_pre(y, )].val);
if(x == )printf("%d\n", t[get_pre(y, )].val);
}
return ;
}

BZOJ 3224 Tyvj 1728 普通平衡树模板的更多相关文章

  1. BZOJ 3224 TYVJ 1728 普通平衡树 [Treap树模板]

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 7390  Solved: 3122 [Submit][S ...

  2. BZOJ 3224: Tyvj 1728 普通平衡树 or 洛谷 P3369 【模板】普通平衡树-Splay树模板题

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 22483  Solved: 10130[Submit][S ...

  3. BZOJ 3224: Tyvj 1728 普通平衡树(BST)

    treap,算是模板题了...我中间还一次交错题... -------------------------------------------------------------------- #in ...

  4. BZOJ 3224: Tyvj 1728 普通平衡树

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 9629  Solved: 4091[Submit][Sta ...

  5. BZOJ 3224: Tyvj 1728 普通平衡树 treap

    3224: Tyvj 1728 普通平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除 ...

  6. BZOJ 3224: Tyvj 1728 普通平衡树 vector

    3224: Tyvj 1728 普通平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除 ...

  7. bzoj 3224: Tyvj 1728 普通平衡树 && loj 104 普通平衡树 (splay树)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3224 思路: splay树模板题: 推荐博客:https://blog.csdn.ne ...

  8. fhq_treap || BZOJ 3224: Tyvj 1728 普通平衡树 || Luogu P3369 【模板】普通平衡树

    题面:[模板]普通平衡树 代码: #include<cstdio> #include<cstring> #include<iostream> #include< ...

  9. BZOJ - 3224 Tyvj 1728 普通平衡树 (treap/树状数组)

    题目链接 treap及树状数组模板题. treap版: #include<bits/stdc++.h> using namespace std; typedef long long ll; ...

随机推荐

  1. C# SocketUdpServer

    public interface ISocketUdpServer { void Start(); void Stop(); int SendData(byte[] data, IPEndPoint ...

  2. Java学习--list,set,Map接口使用

    list接口: 泛型:规定list中的元素的类型 /*     *      * 泛型不能使用基本数据类型(可以使用基本类型的包装类)     *      */    public void tes ...

  3. 十二、curator recipes之双重屏障DoubleBarrier

    简介 curator实现了单个屏障barrier和双重屏障DoubleBarrier,单个屏障就是在一个进程里面设置了屏障,并等待其它进程去移除这个屏障,否则一直阻塞.双重屏障就是设置了两道屏障,两个 ...

  4. 字符串数组中含有json转换

    [{'a':'1','b':'2'},{'c':'3','d':'4'}]" 解决 import net.sf.json.JSONArray; import net.sf.json.JSON ...

  5. 读写csv文件——考虑各种异常场景,源码

    CSV是以逗号间隔的文本文件,其文件以纯文本形式存储表格数据(数字和文本).在JAVA中可以通过输出文件流的方式将数据写入CSV文件,通过BufferedReader类去读该路径中的文件,使用read ...

  6. maven私服的搭建

    前言: 为什么要有maven私服? 当我们在公司开发时,如果每个程序员都需要连接外网去下载maven的jar包,当同时开发时,就会造成网络资源浪费,因此,maven提出了私服的概念,当公司内部程序员进 ...

  7. VPS虚拟化架构OpenVZ、KVM、Xen、Hyper-V的区别

    1.OpenVZ OpenVZ(简称OVZ)采用SWsoft的Virutozzo虚拟化服务器软件产品的内核,是基于Linux平台的操作系统级服务器虚拟化架构.这个架构直接调用宿主机(俗称:母机)中的内 ...

  8. zoj 3747 (DP)(连续至多,连续至少)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5170 参考: http://blog.csdn.net/cc_again/ar ...

  9. Spring的自动装配Bean

    spring的自动装配功能的定义:无须在Spring配置文件中描述javaBean之间的依赖关系(如配置<property>.<constructor-arg>).IOC容器会 ...

  10. JavaWeb学习总结(五):HttpServletRespone对象(一)

    Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象.request和response对象即然代表请求和响应,那我们要 ...