链接:https://codeforces.com/problemset/problem/675/D

题意:

给一个二叉搜索树,一开始为空,不断插入数字,每次插入之后,询问他的父亲节点的权值

题解:

由二叉搜索树的有序性质,

他的父亲节点一定是和他向上和向下最接近的两个中,最后插入的那一个

那么我们对于每一个数字标记其插入的时间,然后维护一棵平衡二叉树用于插值和查找用即可

主要是记录一下我的伸展树代码

据说指针比数组快,但是我这里不仅数组比指针快,甚至用vector和用数组的速度也是一样的

指针:

数组:

1.指针版

#include <bits/stdc++.h>
#define endl '\n'
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int maxn=1e6+10,maxm=2e6+10;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const double PI=acos(-1.0);
//head
int casn,n,m,k;
int num[maxn];
class splaytree{
public:
struct splaynode{
splaynode *son[2],*pre;
ll val;
splaynode(int x=0,splaynode *fa=NULL){
pre=fa;
son[0]=son[1]=NULL;
val=x;
}
};
typedef struct splaynode* nodep;
int cnt;
nodep root;
vector<splaynode> node;
void rotate(nodep now,int d){
nodep fa=now->pre;
fa->son[!d]=now->son[d];
if(now->son[d]) now->son[d]->pre=fa;
now->pre=fa->pre;
if(fa->pre){
if(fa->pre->son[0]==fa) fa->pre->son[0]=now;
else fa->pre->son[1]=now;
}else root=now;
now->son[d]=fa;
fa->pre=now;
}
void splay(nodep now,nodep dst){
while(now->pre!=dst){
if(now->pre->pre==dst)rotate(now,now->pre->son[0]==now);
else{
nodep fa=now->pre;
int d=(fa->pre->son[0]==fa);
if(fa->son[d]==now){
rotate(now,!d);
rotate(now,d);
}else {
rotate(fa,d);
rotate(now,d);
}
}
}
if(!dst) root=now;
}
int insert(int val){
if(!root) {
node[cnt]=splaynode(val);
root=&node[cnt++];
return 0;
}
nodep now=root;
int flag=(now->val)<val;
while(now->son[flag]){
if((now->val)==val){
splay(now,NULL);
return 0;
}
now=now->son[flag];
flag=((now->val)<val);
}
node[cnt]=splaynode(val,now);
now->son[flag]=&node[cnt++];
splay(now->son[flag],NULL);
return 1;
}
int bound(int d){
nodep now=root->son[d];
if(!now) return INF;
while(now->son[d^1]) now=now->son[d^1];
return now->val;
}
splaytree(int n){
cnt=0;
node.resize(n+7);
root=NULL;
}
};
map<int,int> vis;
int main() {
IO;
cin>>n;
splaytree tree(n);
while(n--){
int a;
cin>>a;
vis[a]=maxn-n;
if(!tree.insert(a)) continue;
int mn=tree.bound(0);
int mx=tree.bound(1);
if(vis[mn]>vis[mx]) cout<<mn<<' ';
else cout<<mx<<' ';
}
return 0;
}

2.数组版

#include <bits/stdc++.h>
#define endl '\n'
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int maxn=1e6+10,maxm=2e6+10;
const int INF=0x3f3f3f3f;
int casn,n,m,k;
class splaytree{
#define nd node[now]
public:
struct splaynode{
int son[2],pre;
ll val;
splaynode(int x=0,int fa=0){
pre=fa;
son[0]=son[1]=0;
val=x;
}
};
int cnt;
int root;
vector<splaynode> node;
void rotate(int now,int d){
int fa=nd.pre;
node[fa].son[!d]=nd.son[d];
node[nd.son[d]].pre=fa;
if(node[fa].pre){
node[node[fa].pre].son[node[node[fa].pre].son[1]==fa]=now;
}else root=now;
nd.pre=node[fa].pre;
nd.son[d]=fa;
node[fa].pre=now;
}
void splay(int now,int dst){
while(nd.pre!=dst){
if(node[nd.pre].pre==dst)rotate(now,node[nd.pre].son[0]==now);
else{
int fa=nd.pre;
int d=(node[node[fa].pre].son[0]==fa);
if(node[fa].son[d]==now){
rotate(now,!d);
rotate(now,d);
}else {
rotate(fa,d);
rotate(now,d);
}
}
}
if(!dst) root=now;
}
int insert(int val){
if(!root) {
node[cnt]=splaynode(val);
root=cnt++;
return 0;
}
int now=root;
int flag=nd.val<val;
while(nd.son[flag]){
if(nd.val==val){
splay(now,0);
return 0;
}
now=nd.son[flag];
flag=nd.val<val;
}
node[cnt]=splaynode(val,now);
nd.son[flag]=cnt++;
splay(nd.son[flag],0);
return 1;
}
int bound(int d){
int now=node[root].son[d];
if(!now) return INF;
while(nd.son[d^1]) now=nd.son[d^1];
return nd.val;
}
splaytree(int n){
cnt=1,root=0;
node.resize(n+7);
}
};
map<int,int> vis;
int main() {
IO;
cin>>n;
splaytree tree(n);
while(n--){
int a;
cin>>a;
vis[a]=maxn-n;
if(!tree.insert(a)) continue;
int mn=tree.bound(0);
int mx=tree.bound(1);
if(vis[mn]>vis[mx]) cout<<mn<<' ';
else cout<<mx<<' ';
}
return 0;
}

Codeforces 675D Tree Construction Splay伸展树的更多相关文章

  1. CodeForces 675D Tree Construction

    递归,$RMQ$. 因为$n$较大,可以采用递归建树的策略. 对每一个点标一个$id$.然后按照$v$从小到大排序,每一段$[L,R]$的根节点就是$id$最小的那个. 因为二叉搜索树可能是一条链,所 ...

  2. codeforces 675D Tree Construction set

    转自:http://blog.csdn.net/qwb492859377/article/details/51447350 #include <stdio.h> #include < ...

  3. Splay伸展树学习笔记

    Splay伸展树 有篇Splay入门必看文章 —— CSDN链接 经典引文 空间效率:O(n) 时间效率:O(log n)插入.查找.删除 创造者:Daniel Sleator 和 Robert Ta ...

  4. 【学时总结】◆学时·VI◆ SPLAY伸展树

    ◆学时·VI◆ SPLAY伸展树 平衡树之多,学之不尽也…… ◇算法概述 二叉排序树的一种,自动平衡,由 Tarjan 提出并实现.得名于特有的 Splay 操作. Splay操作:将节点u通过单旋. ...

  5. Splay 伸展树

    废话不说,有篇论文可供参考:杨思雨:<伸展树的基本操作与应用> Splay的好处可以快速分裂和合并. ===============================14.07.26更新== ...

  6. [Splay伸展树]splay树入门级教程

    首先声明,本教程的对象是完全没有接触过splay的OIer,大牛请右上角.. 首先引入一下splay的概念,他的中文名是伸展树,意思差不多就是可以随意翻转的二叉树 PS:百度百科中伸展树读作:BoGa ...

  7. Splay伸展树入门(单点操作,区间维护)附例题模板

    Pps:终于学会了伸展树的区间操作,做一个完整的总结,总结一下自己的伸展树的单点操作和区间维护,顺便给未来的自己总结复习用. splay是一种平衡树,[平均]操作复杂度O(nlogn).首先平衡树先是 ...

  8. [算法] 数据结构 splay(伸展树)解析

    前言 splay学了已经很久了,只不过一直没有总结,鸽了好久来写一篇总结. 先介绍 splay:亦称伸展树,为二叉搜索树的一种,部分操作能在 \(O( \log n)\) 内完成,如插入.查找.删除. ...

  9. CF 675D——Tree Construction——————【二叉搜索树、STL】

    D. Tree Construction time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

随机推荐

  1. python第四次周末大作业

    ''' 选课系统开发 系统登录需要有两类用户:学生.管理员,针对不用用户提供不同功能: 学生用户 :对于学生用户来说,登陆之后有三个功能 1.查看所有课程 2.选择课程 3.查看所选课程 4.删除已选 ...

  2. JavaScript中的this指向规则

    首先,JavaScript的this指向问题并非传说中的那么难,不难的是机制并不复杂,而被认为不好理解的是逻辑关系和容易混淆的执行上下文.这篇博客也就会基于这两个不好理解的角度来展开,如要要严格的来对 ...

  3. @GetMapping(value="/") , "/" 可加可不加 ,是不是一样的

    @GetMapping(value = "/user") 和  @GetMapping(value = "user") 的区别 1.带上 "/&quo ...

  4. HTML第一耍 标题 段落 字体等标签

    1.HTML标题的使用 <!doctype html> <html> <head> <title>文本标签演示</title> </h ...

  5. webService-cxf框架的使用

    webService-cxf框架的使用: 1:简介: wbservice常用框架 Axis: --> Axis2 XFire: -->(Web Service框架) XFire是codeH ...

  6. python生成pdf

    代码 需要先安装wkhtmltopdf,下载路径https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmlto ...

  7. ASP.NET Web API 2 使用 DelegatingHandler(委托处理程序)实现签名认证

    Ø  前言 在前一篇ASP.NET Web API 2 使用 AuthorizationFilter(授权过滤器)实现 Basic 认证文章中实现了采用 Basic 认证的方式,但是这种方式存在安全隐 ...

  8. 15个新鲜出炉的 Photoshop 文本效果教程

    文本效果可能是 Photoshop 图形设计中最常用和最通用的技术之一.最重要的是你可以使用任何效果,风格或纹理来产生有趣的排版,越多人尝试过它并制作了一些精彩的教程.所以这篇文章旨在为您提供全面的 ...

  9. State management(状态管理)

    State management https://en.wikipedia.org/wiki/State_management UI控件的状态管理, 例如按钮的灰化.只读.显示隐藏等. 特殊地一个控件 ...

  10. idea 2018.1破解激活方法,有效期至2099年

    优点:有效期至2099年,不出意外,这辈子肯定够用了 缺点:稍微麻烦些,不过不要紧,为了以后省事,都值了 下面是具体的破解激活步骤: 1. 下载破解补丁文件,路径为:http://idea.lanyu ...