到现在才想起来我还不会写splay……
QAQ
在DQS学长写模板的时候带了我下……
QAQ人生第一个维护数的splay
QAQQQQQQQ
要记得在del、rot、newnode这种设计更新根的操作的时候一定要root = x;root -> f = null
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 100000 + 5;
struct tr
{
tr *ch[2],*f;
int v,sz,cnt;
bool dir()
{
return f -> ch[1] == this;
}
void maintain()
{
sz = cnt + ch[0] -> sz + ch[1] -> sz;
return;
}
void setc(tr *p,int d)
{
(ch[d] = p) -> f = this;
return;
}
}tree[MAXN],*root,*null;
int tot = 0;
tr* newnode(int x,tr* fa = null)
{
tr *p = tree + (tot ++);
p -> f = fa;
p -> ch[0] = p -> ch[1] = null;
p -> sz = p -> cnt = 1;
p -> v = x;
return p;
}
void reset()
{
tot = 0;
null = newnode(0);
null -> sz = null -> cnt = 0;
root = null;
return;
}
void rot(tr *x)
{
tr *p = x -> f;
int d = x -> dir();
p -> f -> setc(x,p -> dir());
p -> setc(x -> ch[d ^ 1],d);
p -> maintain();
x -> setc(p,d ^ 1);
x -> maintain();
if(p == root)
root = x;
return;
}
void splay(tr* x,tr* to = null)
{
while(x -> f != to)
{
if(x -> f -> f == to)
rot(x);
else
x -> dir() == x -> f -> dir() ? (rot(x -> f),rot(x)) : (rot(x),rot(x));
}
}
void insert(int x)
{
if(root == null)
{
root = newnode(x);
return;
}
tr* p = root;
while(p != null)
{
p -> sz ++;
if(p -> v == x)
{
p -> cnt++;
break;
}
int d = x > p -> v;
if(p -> ch[d] == null)
{
p -> ch[d] = newnode(x,p);
p = p -> ch[d];
break;
}
p = p -> ch[d];
}
splay(p);
return;
}
tr* find(int x)
{
tr* p = root;
while(p != null)
{
if(p -> v == x)
break;
int d = x > p -> v;
p = p -> ch[d];
}
splay(p);
return p;
}
void del(int x)
{
tr *p = find(x);
splay(p);
p -> sz --;
if(--p -> cnt)
return;
if(p -> ch[0] == null){root = p -> ch[1];root -> f = null;return;}
if(p -> ch[1] == null){root = p -> ch[0];root -> f = null;return;}
p = p -> ch[0];
while(p -> ch[1] != null)
p = p -> ch[1];
splay(p,root);
p -> setc(root -> ch[1],1);
p -> f = null;
p -> maintain();
root = p;
return;
}
int find_hj(int x)
{
tr* p = root;
int ans = 0;
while(p != null)
{
if(x < p -> v)
ans = p -> v,p = p -> ch[0];
else
p = p -> ch[1];
}
return ans;
}
int find_qq(int x)
{
tr* p = root;
int ans = 0;
while(p != null)
{
if(x > p -> v)
ans = p -> v,p = p -> ch[1];
else
p = p -> ch[0];
}
return ans;
}
int num_to_pm(int x)
{
splay(find(x));
return root -> ch[0] -> sz + 1;
}
int pm_to_num(int x)
{
tr* p = root;
while(p != null)
{
int l = p -> ch[0] -> sz + 1;
int r = p -> ch[0] -> sz + p -> cnt;
if(l <= x && x <= r)
return p -> v;
int d = x > p -> ch[0] -> sz + p -> cnt;
if(d)
x -= p -> ch[0] -> sz + p -> cnt;
p = p -> ch[d];
}
return p -> v;
}
int n,q,x;
int main()
{
reset();
scanf("%d",&n);
while(n --)
{
scanf("%d",&q);
switch(q)
{
case 1:scanf("%d",&x);insert(x);break;
case 2:scanf("%d",&x);del(x);break;
case 3:scanf("%d",&x);printf("%d\n",num_to_pm(x));break;
case 4:scanf("%d",&x);printf("%d\n",pm_to_num(x));break;
case 5:scanf("%d",&x);printf("%d\n",find_qq(x));break;
case 6:scanf("%d",&x);printf("%d\n",find_hj(x));break;
}
}
return 0;
}