Splay树求第k大模板
今天上午借着休息日得机会手撸了一下模板,终于对着模板调出来了。prev和next占用了std namespace里面的东西,然后报警我上次给关了所以。。。。。就花了3个小时吧。
inline加不加无所谓,但是代码规范一定要有。

#include <bits/stdc++.h>
using namespace std;
#define limit (1000000 + 5)//防止溢出
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f
#define lowbit(i) i&(-i)//一步两步
#define EPS 1e-6
#define FASTIO ios::sync_with_stdio(false);cin.tie(0);
#define ff(a) printf("%d\n",a );
#define pi(a,b) pair<a,b>
#define rep(i, a, b) for(ll i = a; i <= b ; ++i)
#define per(i, a, b) for(ll i = b ; i >= a ; --i)
#define MOD 998244353
#define traverse(u) for(int i = head[u]; ~i ; i = edge[i].next)
#define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\acm_01\\data.txt", "rt", stdin)
#define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\acm_01\\dabiao.txt", "wt", stdout)
#define debug(x) cout<<x<<endl
typedef long long ll;
typedef unsigned long long ull;
inline ll read(){
ll sign = 1, x = 0;char s = getchar();
while(s > '9' || s < '0' ){if(s == '-')sign = -1;s = getchar();}
while(s >= '0' && s <= '9'){x = (x << 3) + (x << 1) + s - '0';s = getchar();}
return x * sign;
}//快读
void write(ll x){
if(x < 0) putchar('-'),x = -x;
if(x / 10) write(x / 10);
putchar(x % 10 + '0');
}
struct node{
node *son[2], *fa;//确定三个最重要的
int key,cnt,size;
node():fa(nullptr),key(0),cnt(0),size(0){
son[0] = son[1] = nullptr;
} bool get(){
return fa->son[1] == this;
}
void update(){
size = son[1]->size + son[0]->size + cnt;
}
void clear(){
key = cnt = size = 0;
}
}tree[limit],*root,*null;
int n,tot;
node* make_tree_node(){
++tot;
tree[tot].son[0] = tree[tot].son[1] = tree[tot].fa = null;
return &tree[tot];
}
inline void rotate(node *cur){
node *fa = cur->fa,*grandfather = fa->fa;
int rt = cur->get(), rt2 = fa->get();
fa->son[rt] = cur->son[rt ^ 1];
fa->son[rt]->fa = fa;
cur->son[rt ^ 1] = fa;
fa->fa = cur;
cur->fa = grandfather;
if(grandfather != null)
grandfather->son[rt2] = cur;
fa->update();
cur->update();
}
inline void splay(node *cur){
for(node *fa = null ;(fa=cur->fa) != null;rotate(cur)) {
if (fa->fa != null) {
rotate((fa->get() == cur->get()) ? fa : cur);
}
}
root = cur;
}
inline void insert(int x){
if(root == null){
root = make_tree_node();
root->key = x;
root->cnt = root->size = 1;
return;
} for(node *cur = root,*fa = null; ; ){
if(x == cur->key){
cur->cnt++;
splay(cur);
return;
}
fa = cur;
cur = cur->son[x > cur->key];
if(cur == null){
fa->son[x > fa->key]= cur = make_tree_node();
cur->key = x;
cur->cnt=1;
cur->fa=fa;
splay(cur);
return;
}
}
}
int kth(int k){
//求解k大
for(node * cur = root;;){
if(cur->son[0] != null && k <= cur->son[0]->size){
cur = cur->son[0];
}else{
int left_size = cur->son[0]->size + cur->cnt;
if(k <= left_size)return cur->key;
k -= left_size;
cur = cur->son[1];
}
}
}
int rank(int x){
int ans = 0;
for(node * cur = root; ; ){
if(cur->son[0] != null && x < cur->key)cur = cur->son[0];
else{
ans += cur->son[0]->size;
if(cur->key == x){
splay(cur);
return ans;
}
ans += cur->cnt;
cur = cur->son[1];
}
}
}
node * pre(){//前驱
node * cur = root->son[0];
for(;cur->son[1] != null;cur = cur->son[1]);
return cur;
}
void del(int x){
::rank(x);
if(root->cnt > 1){
root->cnt--;
root->update();
return;
}
node * l = pre(), *oldroot = root;
splay(l);
l->son[1] = oldroot->son[1];
l->son[1]->fa = l;
oldroot->clear();
root->update();
}
int prev(node * rt, int val){
if(rt == null)return -INF;
if(val > rt->key)return max(rt->key,::prev(rt->son[1],val));
else return ::prev(rt->son[0],val);
}
int next(node * rt, int val){
if(rt == null)return INF;
if(val < rt->key)return min( rt->key,::next(rt->son[0],val));
else return ::next(rt->son[1],val);
}
int main() {
#ifdef LOCAL
FOPEN;
#endif
tot = 0;
null = root = &tree[0];
n = read();
insert(INF), insert(-INF);
while (n--){
int op = read(), x = read();
if(op == 1){
insert(x);
}else if(op == 2){
del(x);
}else if(op == 3){
ff(::rank(x));
}else if(op == 4){
ff(kth(x + 1));
}else if(op == 5){
ff(::prev(root, x));
}else{
ff(::next(root,x))
}
}
return 0;
}
Splay Tree
Splay树求第k大模板的更多相关文章
- poj 2985 The k-th Largest Group 树状数组求第K大
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8353 Accepted ...
- HDU 5249 离线树状数组求第k大+离散化
KPI Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- POJ 2985 Treap平衡树(求第k大的元素)
这题也能够用树状数组做,并且树状数组姿势更加优美.代码更加少,只是这个Treap树就是求第K大元素的专家--所以速度比較快. 这个也是从那本红书上拿的模板--自己找了资料百度了好久,才理解这个Trea ...
- 面试题:求第K大元素(topK)?
一.引言二.普通算法算法A:算法B:三.较好算法算法C:算法D:四.总结 一.引言 这就是类似求Top(K)问题,什么意思呢?怎么在无序数组中找到第几(K)大元素?我们这里不考虑海量数据,能装入内 ...
- 《数据结构与算法分析:C语言描述》读书笔记------练习1.1 求第K大的数
求一组N个数中的第k个最大者,设k=N/2. import java.util.Random; public class K_Max { /** * @param args */ //求第K大的数,保 ...
- 快排法求第k大
快排法求第k大,复杂度为O(n) import com.sun.media.sound.SoftTuning; import java.util.Arrays; import java.util.Ra ...
- HDU 2639 01背包求第k大
Bone Collector II Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- BZOJ2006:超级钢琴(ST表+堆求前K大区间和)
Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度 ...
- ACM_求第k大元素(两次二分)
求第k大 Time Limit: 6000/3000ms (Java/Others) Problem Description: 给定两个数组A和B,大小为N,M,每次从两个数组各取一个数相乘放入数组C ...
随机推荐
- [Codeforces 580D]Fizzy Search(FFT)
[Codeforces 580D]Fizzy Search(FFT) 题面 给定母串和模式串,字符集大小为4,给定k,模式串在某个位置匹配当且仅当任意位置模式串的这个字符所对应的母串的位置的左右k个字 ...
- Mybatis 批量更新遇到的小问题
小问题 记一个开发过程中因为小细节的遗漏而引发的 "莫名其妙",公司中有个2B(to B)供应链项目,持久层用的是 JPA,这里我就不吐槽 JPA 了,这种 SQL 嵌入在代码里的 ...
- 【SpringBoot】08.SpringBoot整合jsp
SpringBoot整合jsp 1.修改pom文件加入两个坐标jstl标签库和jasper <project xmlns="http://maven.apache.org/POM/4. ...
- vgg学习
LeNet-5是一个较简单的卷积神经网络.下图显示了其结构:输入的二维图像,先经过两次卷积层到池化层,再经过全连接层,最后使用softmax分类作为输出层. AlexNet中包含了几个比较新的技术点, ...
- leetcode75:search-a-2d-matrix
题目描述 请写出一个高效的在m*n矩阵中判断目标值是否存在的算法,矩阵具有如下特征: 每一行的数字都从左到右排序 每一行的第一个数字都比上一行最后一个数字大 例如: 对于下面的矩阵: [ [1, 3, ...
- OpenCV计算机视觉学习(11)——图像空间几何变换(图像缩放,图像旋转,图像翻转,图像平移,仿射变换,镜像变换)
如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 图像 ...
- select模型(一 改进客户端)
一.改程序使用select来改进客户端对标准输入和套接字输入的处理,否则关闭服务器之后循环中的内容都要被gets阻塞.原程序中https://www.cnblogs.com/wsw-seu/p/841 ...
- python脚本打包成rpm软件包
前言 软件最终都会有交付的形式,有的是用tar包,有个是以目录,有的是封成一个文件包,从大多数使用场景来说,直接打包成软件包的方式是最简单,也是最不容易出错的,路径可以在包里面写死了 实践 关于打包的 ...
- ESP8266 鼓捣记 - 从零制作一个温湿度计
一.前言 经过上一篇文章 <ESP8266 鼓捣记 - 入门(环境搭建) >搭建好环境后,肯定不会满足于 Hello World ,想快速做一个实际有用的东西出来,我认为温湿度计就非常合适 ...
- 测试_QTP使用
1.Qtp是什么? QTP是Quick Test Professional的简称,是一种自动测试工具.使用QTP的目的是想用它来执行重复的自动化测试,主要是用于回归测试和测试同一软件的新版本.(百度百 ...