splay 模板 洛谷3369
题目描述
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
插入 xx 数 
删除 xx 数(若有多个相同的数,因只删除一个) 
查询 xx 数的排名(排名定义为比当前数小的数的个数 +1+1 。若有多个相同的数,因输出最小的排名) 
查询排名为 xx 的数 
求 xx 的前驱(前驱定义为小于 xx ,且最大的数) 
求 xx 的后继(后继定义为大于 xx ,且最小的数) 
输入输出格式
输入格式: 
第一行为 nn ,表示操作的个数,下面 nn 行每行有两个数 optopt 和 xx , optopt 表示操作的序号( 1 \leq opt \leq 6 1≤opt≤6 )
输出格式: 
对于操作 3,4,5,63,4,5,6 每行输出一个数,表示对应答案
输入输出样例
输入样例#1: 复制 
10 
1 106465 
4 1 
1 317721 
1 460929 
1 644985 
1 84185 
1 89851 
6 81968 
1 492737 
5 493598 
输出样例#1: 复制 
106465 
84185 
492737 
说明
时空限制:1000ms,128M
1.n的数据范围: n \leq 100000 n≤100000
2.每个数的数据范围: [-{10}^7, {10}^7][−10  
7 
 ,10  
7 
 ]
来源:Tyvj1728 原名:普通平衡树
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 100005;
const int inf = 0x7f7f7f7f;
struct Node{
    int v,fa;
    int ch[2];
    int sum;
    int recy;
}node[MAXN];
int n,cnt,points;
inline void update(int x){
    node[x].sum=node[node[x].ch[1]].sum+node[node[x].ch[0]].sum+node[x].recy;
}
inline bool jud(int x){
    return node[node[x].fa].ch[0]==x?0:1;
}
inline void connect(int x,int f,int son){
    node[x].fa=f;
    node[f].ch[son]=x;
}
inline void rotate(int x){
    int y=node[x].fa;
    int mroot=node[y].fa;
    int mrootson=jud(y);
    int yson=jud(x);
    int oth=node[x].ch[yson^1];
    connect(oth,y,yson);
    connect(y,x,(yson^1));
    connect(x,mroot,mrootson);
    update(y);update(x);
}
inline void splay(int at,int to){
    to=node[to].fa;
    while(node[at].fa!=to){
        int up=node[at].fa;
        if(node[up].fa==to) rotate(at);
        else if(jud(up)==jud(at)){
            rotate(up);
            rotate(at);
        }
        else{
            rotate(at);
            rotate(at);
        }
    }
}
inline int crepoint(int x,int f){
    node[++cnt].v=x;
    node[cnt].fa=f;
    node[cnt].sum=1;
    node[cnt].recy=1;
    return cnt;
}
inline void destroy(int x){
    node[x].v=node[x].fa=node[x].sum=node[x].recy=node[x].ch[0]=node[x].ch[1]=0;
    if(x==cnt) cnt--;
}
inline int find(int v){
    int now=node[0].ch[1];
    while(1){
        if(node[now].v==v){
            splay(now,node[0].ch[1]);
            return now;
        }
        int nxt=v<node[now].v?0:1;
        if(!node[now].ch[nxt]) return 0;
        now=node[now].ch[nxt];
    }
}
inline int build(int x){
    points++;
    if(cnt==0){
        node[0].ch[1]=1;
        crepoint(x,0);
    }
    else{
        int now=node[0].ch[1];
        while(1){
            node[now].sum++;
            if(x==node[now].v){
                node[now].recy++;
                return now;
            }
            int nxt=x<node[now].v?0:1;
            if(!node[now].ch[nxt]){
                crepoint(x,now);
                node[now].ch[nxt]=cnt;
                return cnt;
            }
            now=node[now].ch[nxt];
        }
    }
    return 0;
}
inline void push(int x){
    int add=build(x);
    splay(add,node[0].ch[1]);
}
inline void pop(int v){
    int deal=find(v);
    if(!deal) return;
    points--;
    if(node[deal].recy>1){
        node[deal].recy--;
        node[deal].sum--;
        return;
    }
    if(!node[deal].ch[0]){
        node[0].ch[1]=node[deal].ch[1];
        node[node[0].ch[1]].fa=0;
    }
    else{
        int lef=node[deal].ch[0];
        while(node[lef].ch[1]) lef=node[lef].ch[1];
        splay(lef,node[deal].ch[0]);
        int rig=node[deal].ch[1];
        connect(rig,lef,1);connect(lef,0,1);
        update(lef);
    }
    destroy(deal);
}
int rank(int x){
    int ans=0;
    int now=node[0].ch[1];
    while(1){
        if(node[now].v==x) return ans+node[node[now].ch[0]].sum+1;
        if(now==0) return 0;
        if(x<node[now].v) now=node[now].ch[0];
        else{
            ans+=node[node[now].ch[0]].sum+node[now].recy;
            now=node[now].ch[1];
        }
    }
    if(now) splay(now,node[0].ch[1]);
    return 0;
}
int atrank(int x){
    if(x>points)    return -inf;
    int now=node[0].ch[1];
    while(1){
        int minn=node[now].sum-node[node[now].ch[1]].sum;
        if(x>node[node[now].ch[0]].sum && x<=minn) break;
        if(x<minn) now=node[now].ch[0];
        else{
            x=x-minn;
            now=node[now].ch[1];
        }
    }
    splay(now,node[0].ch[1]);
    return node[now].v;
}
inline int lower(int x){
    int now=node[0].ch[1];
    int res=-inf;
    while(now){
        if(node[now].v<x && node[now].v>res) res=node[now].v;
        if(x>node[now].v) now=node[now].ch[1];
        else now=node[now].ch[0];
    }
    return res;
}
inline int upper(int x){
    int now=node[0].ch[1];
    int res=inf;
    while(now){
        if(node[now].v>x && node[now].v<res) res=node[now].v;
        if(x<node[now].v) now=node[now].ch[0];
        else now=node[now].ch[1];
    }
    return res;
}
int main(){
    scanf("%d",&n);
    push(inf);push(-inf);
    for(register int i=1;i<=n;i++){
        int opt,x;
        scanf("%d%d",&opt,&x);
        if(opt==1) push(x);
        else if(opt==2) pop(x);
        else if(opt==3) printf("%d\n",rank(x)-1);
        else if(opt==4) printf("%d\n",atrank(x+1));
        else if(opt==5) printf("%d\n",lower(x));
        else printf("%d\n",upper(x));
    }
    return 0;
}splay 模板 洛谷3369的更多相关文章
- 【数论】卢卡斯定理模板 洛谷P3807
		[数论]卢卡斯定理模板 洛谷P3807 >>>>题目 [题目] https://www.luogu.org/problemnew/show/P3807 [输入格式] 第一行一个 ... 
- KMP字符串匹配 模板 洛谷 P3375
		KMP字符串匹配 模板 洛谷 P3375 题意 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.(如果 ... 
- 在洛谷3369 Treap模板题 中发现的Splay详解
		本题的Splay写法(无指针Splay超详细) 前言 首先来讲...终于调出来了55555...调了整整3天..... 看到大部分大佬都是用指针来实现的Splay.小的只是按照Splay的核心思想和原 ... 
- BZOJ3224 洛谷3369 Tyvj 1728 普通平衡树 splay
		欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3224 题意概括 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. ... 
- 【模板】LIS模板 洛谷P1091 [NOIP2004提高组]合唱队形 [2017年4月计划 动态规划11]
		以题写模板. 写了两个:n^2版本与nlogn版本 P1091 合唱队形 题目描述 N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形. 合唱队形是指这样的一种队 ... 
- 树链剖分模板(洛谷P3384)
		洛谷P3384 #include <bits/stdc++.h> #define DBG(x) cerr << #x << " = " < ... 
- (treap)[bzoj3224][洛谷3369][cogs1829]Tyvj 1728 普通平衡树
		Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数 ... 
- 洛谷.3369.[模板]普通平衡树(Splay)
		题目链接 第一次写(2017.11.7): #include<cstdio> #include<cctype> using namespace std; const int N ... 
- 【Splay】洛谷3372 【模板】线段树 1
		Splay区间加,询问区间和. #include<cstdio> #include<iostream> #include<cstring> #include< ... 
随机推荐
- Jmeter-【If控制器】-__jexl3函数&__groovy函数
			一.使用场景 根据请求返回结果中某一字段的取值判断往下走的流程.例如: 二.__jexl3函数实现 格式:${__jexl3(,)} 三.__groovy函数实现 格式:${__groovy(,)} 
- ueditor不能上传mp4格式的视频--解决方案
			1.ueditor.all.js 去掉所有的 type="application/x-shockwave-flash" 2.ueditor.all.min.js 去掉所有的 typ ... 
- 2019 wannafly winter camp day5-8代码库
			目录 day5 5H div2 Nested Tree (树形dp) 5F div2 Kropki (状压dp) 5J div1 Special Judge (计算几何) 5I div1 Sortin ... 
- Go 方法、接口
			在 Go 中,类型可以定义接收此类型的函数,即方法.每个类型都有接口,意味着对那个类型定义了方法集合. 下面定义了结构体类型 S 以及它的两个方法: type S struct { i int ... 
- FM算法组合估计
			#include <stdio.h> #include <math.h> #include <stdlib.h> #include <time.h> # ... 
- Dubbo入门到精通学习笔记(八):ActiveMQ的安装与使用(单节点)、Redis的安装与使用(单节点)、FastDFS分布式文件系统的安装与使用(单节点)
			文章目录 ActiveMQ的安装与使用(单节点) 安装(单节点) 使用 目录结构 edu-common-parent edu-demo-mqproducer edu-demo-mqconsumer 测 ... 
- smali与baksmali用法-基于2.2.2版本
			下载地址:https://bitbucket.org/JesusFreke/smali/downloads/?tab=downloads 反编译dex java -jar baksmali-2.2.1 ... 
- vue组件通信之非父子组件通信
			什么顺序不顺序的.. 先来说说非父子组件通信. 首先,我们先来了解下vue中的 1.$emit 触发当前实例上的事件,附加参数都会传给监听器回调. 2.$on 监听当前实例上的自定义事件.事件可以 ... 
- error C4996: 'getcwd': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _getcwd. See online help for details.	c:\users\12968\desktop\testapp\testapp\testapp.c
			解决办法: 属性>C/C++>预处理器定义>分别输入: _CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE >保存退出即可 
- centos7.3 编译安装 git 2.13
			安装依赖包 sudo yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-devel 安装 $ ... 
