[知识点]Treap 指针实现

其实平衡树这个东东,我原来也是打过那么几遍的,而且三种基本的都打过了。但是呢,当时内心抵触指针,于是就用的网上的数组平衡树模板

理解起来倒是没什么问题,无奈码量略大T_T

然后就有一段时间没打平衡树了。这两天刷数据结构专题,发现一道 [HNOI 2012]永无乡 需要建多颗平衡树。

我靠!这是对我的数组平衡树的毁灭性的打击啊!!

于是狠了狠心,学指针打法!

然后hww神牛为我提供了他的板子。照着打了不到一个小时,发现指针实现的话,码量灰常小的,而且也很好理解的!

于是乎我现在满心欢喜。不过悲催的是我的splay还是用数组实现的T_T。找个机会把splay也改成指针打法。

嗯。先把Treap搞定了。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
#define N 101000
#include<cstdlib>
#define size(x) ((x)?(x->size):(0))
#define ls(x) (x->ch[0])
#define rs(x) (x->ch[1])
int n;
struct Treap{
	int size,v,key;
	Treap *ch[2];
	Treap(int x=0){
		v=x;size=1;key=rand();ch[0]=ch[1]=NULL;
	}
}*root;
void pushup(Treap *rt){
	rt->size=size(ls(rt))+size(rs(rt))+1;
}
void turn(Treap *&rt,int d){
	Treap *t=rt->ch[d^1];
	rt->ch[d^1]=t->ch[d];pushup(rt);
	t->ch[d]=rt;pushup(t);
	rt=t;
}
void insert(Treap *&rt,int x){
	if(!rt){
		rt=new Treap(x);return;
	}
	int d=x < rt->v;
	insert(rt->ch[d^1],x);
	pushup(rt);
	if(rt->ch[d^1]->key < rt->key) turn(rt,d);
}
void del(Treap *&rt,int x){
	if(rt->v==x){
		if(ls(rt)&&rs(rt)){
			int d=ls(rt)->key < rs(rt)->key;
			turn(rt,d);del(rt->ch[d],x);
		}
		else{
			Treap *t=NULL;
			if(ls(rt)) t=ls(rt);
			else t=rs(rt);
			delete rt;rt=t;
		}
	}
	else{
		int d=x < rt->v;
		del(rt->ch[d^1],x);
	}
	if(rt) pushup(rt);
}
int Rank(int x){
	Treap *rt=root;
	int ans(0);
	while(rt){
		if(x > rt->v){
			ans+=size(ls(rt))+1;
			rt=rs(rt);
		}
		else rt=ls(rt);
	}
	return ans;
}
int kth(int k){
	Treap *rt=root;
	while(rt){
		if(size(ls(rt))+1==k) return rt->v;
		if(size(ls(rt))+1>k) rt=ls(rt);
		else{
			k-=size(ls(rt))+1;rt=rs(rt);
		}
	}
	return 0;
}
int main(){
	scanf("%d",&n);
    pos(i,1,n){
    	int opt,x;
        scanf("%d%d",&opt,&x);
        if(opt==1)
            insert(root,x);
        else if(opt==2)
            del(root,x);
        else if(opt==3)
            printf("%d\n",Rank(x)+1);
        else if(opt==4)
            printf("%d\n",kth(x));
        else if(opt==5)
            printf("%d\n",kth(Rank(x)));
        else if(opt==6)
            printf("%d\n",kth(Rank(x+1)+1));
    }
	return 0;
}

  

时间: 2024-12-25 07:53:08

[知识点]Treap 指针实现的相关文章

STM32——C语言知识点:指针、结构体

1 /* 2 ============================================================================ 3 Name : Cyuyanfuxi.c 4 Author : 5 Version : 6 Copyright : Your copyright notice 7 Description : Hello World in C, Ansi-style 8 ======================================

C++_知识点_指针类型转换

#include <iostream> using namespace std; int main(){ short int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int* p = (int*)arr; for(; p <= ((int*)(&arr[10])); ++p){ cout << "*p = " << *p << endl; } return 0; } 0 1 2 3

C语言--&gt;(十)指针基础

知识点: 1.指针基础 2.指针和函数(地址传递) ======================================= 指针是C中的一个重要的概念,也是C的一个重要特色.掌握指针的应用,可以使程序简洁.紧凑.高效. 指针的概念比较复杂,使用也比较灵活,因此初学时会常出错,我们要理解每一个概念的本质,多加练习,在实践中掌握它. 程序使用指针和没有没有使用指针的代码是两个档次. ========================================指针基础 [地址概念] 1.生

C语言:通过函数指针来完成两个数的加减乘除(函数指针当做参数使用)

// //  main.c //  Function_pointer // //  Created by mac on 15/8/2. //  Copyright (c) 2015年 bjsxt. All rights reserved. //  要求:将函数指针做参数来求两个整数的和.差.积.商. //知识点:函数指针就是一个指向函数的指针,通过指针指向要调用的函数来完成操作.其实,这个指针就是指向函数的入口地址. //切记:要被调用的函数必须和函数指针的声明的一样(包括:返回值类型.参数个数

C语言--&gt;(十二)高级指针

知识点: 1.指针数组 指针数组 指向数组的指针 2.返回指针的函数 3.指向函数的指针 block 4.空类型指针 (通用类型指针) 5.二级指针 ==============================指针数组 一个数组,若其元素均为指针类型数据,则该元素称指针数组,也就是说指针数组中每一个元素都存放一个地址,相当于一个指针变量. 1.什么是指针数组(指针的集合) 1)存储指针的数组 2)所有元素均为指针的数组 2.本质 1)指针数组本质仍然为一个数组 2)每一个存储元素均为指向相同类型

C语言:通过函数指针来完成两个数的加减乘除

// //  main.c //  Function_pointer // //  Created by mac on 15/8/2. //  Copyright (c) 2015年 bjsxt. All rights reserved. //  要求:通过函数指针求两个整数的和.差.积.商. //知识点:函数指针就是一个指向函数的指针,通过指针指向要调用的函数来完成操作. //切记:要被调用的函数必须和函数指针的声明的一样(包括:返回值类型.参数个数和类型) #include <stdio.h

指针练习

PTA 实验作业 题目1 :6-5 利用指针找最大值 本题题目及裁判测试程序样例 本题要求实现一个简单函数,找出两个数中的最大值. 1. 本题PTA提交列表 2. 本题设计思路 这道函数题要求我们用指针的方式来找出两个数中的最大值. 其中px和py是题目中定义的用户传入的两个整数的指针.也就是我们要比较的两个数. 函数findmax应找出两个指针所指向的整数中的最大值,存放在pmax指向的位置. 首先当在子函数传入两个数之后,先判断两个指针所指向的数值之差. 如果*px>*py 则令* pmax

函数和指针

1.指针与函数的返回值 1 #define A 0 2 int funcA(int a, int b) 3 { 4 return a + b; 5 } 6 7 /*把指针作为函数的返回值*/ 8 int * funcB(int a, int b) 9 { 10 static int c = A; 11 c = a + b; 12 return &c; 13 } 14 /*通过函数进行内存的申请*/ 15 /* 16 * 参数:要申请的内存大小 17 * 返回值:申请好的内存的首地址 18 * 这

C++ const 常量指针

如果发现本篇的内容不适合你, 可以查看 C++指针目录 在上一章中, 我们了解到了 C++普通指针的用法 在这一章中, 我们需要学会熟练地运用 const, 才可以进入以下部分, 不熟悉的可以看: C++ const用法 好了, 进入正题, 现在会使用一些普通的指针, 但是不知道大家有没有想过: 如果一个指针是 const 怎么办? 当我们声明一个 const指针有两种写法: (字符指针除外) const int* p; 或 int* const p; 两种方法等效 我们需要知道: const