splay

来源:互联网 发布:软件源码买卖合同 编辑:程序博客网 时间:2024/04/19 15:16

splay是省选、noi常用算法,但它过于繁琐、、、、、

实在难打,而且很容易错。

下面是框架和注意点,千万别出错:





易错点:

1、忘update()

2、连接直接写pre

3、忘splay

4、splay判断一条线

5、splay循环判断中出现null

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <iostream>
using namespace std;
struct tree
{
int size,cnt,zhi;
tree *fu,*ch[2];

void update()
{
size=ch[0]->size+ch[1]->size+cnt;
}
int getwh()
{
return fu->ch[0]==this?0:1;
}
void set(int wh,tree *child);
}pool[100000],*root,*null;


 void tree::set(int wh,tree *child)
{
ch[wh]=child;
if(child!=null) //神TM防不胜防 
child->fu=this;
update();
}
int tot=0;
inline tree *jian(int zhi)
{
tree *xin=pool+ ++tot;
xin->fu=xin->ch[0]=xin->ch[1]=null;
xin->cnt=1;
xin->size=1;
xin->zhi=zhi;
return xin;
}
inline void rotate(tree *&now)
{
tree *fu=now->fu;
tree *ye=now->fu->fu;
        int wh=now->getwh();
fu->set(wh,now->ch[wh^1]);
now->set(wh^1,fu);
 now->fu=ye;
 if(ye!=null)
 ye->ch[ye->ch[0]==fu?0:1]=now;
}
inline void splay(tree *now,tree *tar)
{
for(;now->fu!=tar;rotate(now))
        if(now->fu->fu!=tar)
now->getwh()==now->fu->getwh()?rotate(now->fu):rotate(now);
 
if(tar==null)
  root=now;
}
void insert(int zhi)
{
tree *newone=jian(zhi);
tree *last=null,*now=root;
while(now!=null)
{
last=now;
if(now->zhi==zhi)
{
now->cnt++,now->size++;
splay(now,null);
return;
}
if(now->zhi>zhi)
now=now->ch[0];
else now=now->ch[1];
}
if(last==null)
root=newone;
else 
{
if(last->zhi>zhi)
last->set(0,newone);
else
last->set(1,newone);
splay(newone,null);
}
}
inline tree *find(int zhi)
{
tree *now=root;
while(now!=null)
{  
  if(now->zhi==zhi)break;
 if(now->zhi>zhi)
  now=now->ch[0];
  else now=now->ch[1];
}
if(now!=null)splay(now,null);
     return now;
}
inline int pre(int value)
{
int ans = -1000000000;
tree *now = root;
while (now != null)
{
if (now->zhi < value)
{
ans = max(ans, now->zhi);
now = now->ch[1];
} else
now = now->ch[0];
}
return ans;
}
inline int nxt(int value)
{
int ans = 1000000000;
tree *now = root;
while (now != null)
{
if (now->zhi > value)
{
ans = min(ans, now->zhi);
now = now->ch[0];
} else
now = now->ch[1];
}
return ans;
}
void del(int value)
{
tree *now = find(value);
if (now == null) return;
if (now->cnt > 1)
{
now->cnt--;
now->size--;
return;
}


if (now->ch[0] == null && now->ch[1] == null)
root = null;
else if (now->ch[1] == null)
{
now->ch[0]->fu = null;
root = now->ch[0];
}
else if (now->ch[0] == null)
{
now->ch[1]->fu = null;
root = now->ch[1]; 
}
else
{
tree *_ = now->ch[0];
while (_->ch[1] != null) _ = _->ch[1];
splay(_, now);  
_->set(1, now->ch[1]);  
_->fu = null;
root = _;
}
}
inline int get_rank(int value)
{
tree *now = root;
int left_size = 0;
while (now != null)
{
if (value == now->zhi)
{
int ans = left_size + now->ch[0]->size + 1;
splay(now, null);
return ans;
}
if (value < now->zhi)  
now = now->ch[0];
else
left_size += now->ch[0]->size + now->cnt, now = now->ch[1];
}
return -1;
}
inline int kth(int k)
{
tree *now = root;
int left_size = 0;
while (now != null)
{
int _ = left_size + now->ch[0]->size;
if (_ + 1 <= k && k <= _ + now->cnt)
{
splay(now, null);
return now->zhi;
}
if (k <= _) now = now->ch[0];
else left_size = _ + now->cnt, now = now->ch[1]; 
}
return -1;
}
int q,uuu,ling;
int main()
{
null=pool;
null->zhi=0;
null->fu=null->ch[0]=null->ch[1]=null;
null->size=0;
null->cnt=0;
root=null;


}



0 0
原创粉丝点击