链接:https://codeforces.com/problemset/problem/675/D
题意:
给一个二叉搜索树,一开始为空,不断插入数字,每次插入之后,询问他的父亲节点的权值
题解:
由二叉搜索树的有序性质,
他的父亲节点一定是和他向上和向下最接近的两个中,最后插入的那一个
那么我们对于每一个数字标记其插入的时间,然后维护一棵平衡二叉树用于插值和查找用即可
主要是记录一下我的伸展树代码
1.指针版
#include <bits/stdc++.h>
#define endl ‘\n‘
#define ll long long
#define IO ios::sync_with_stdio(false)
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 1;
}
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.root==NULL){
tree.insert(a);
continue;
}
if(tree.insert(a)==0) 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伸展树
原文:https://www.cnblogs.com/nervendnig/p/10225373.html