保留几个还没有看完的网页
https://www.sogou.com/sogou?query=splay%E5%A5%97%E7%BA%BF%E6%AE%B5%E6%A0%91&ie=utf8&_ast=1491658880&_asf=null&w=01029901&pid=sogou-clse-60a70bb05b08d6cd&duppid=1&cid=&cid=&sut=3100&sst0=1491659185439&lkt=0%2C0%2C0&sugsuv=00E601EC791FCD1758E8C284B93A4997&sugtime=1491659185439
http://blog.csdn.net/chunkitlau/article/details/51787319
http://www.sogou.com/tx?user_ip=121.31.205.23&sourceid=hint&bh=1&hintidx=1&query=splay%E6%A0%91&hdq=sogou-site-706608cfdbcc1886-0001&duppid=1&cid=qb7.zhuye&w=01020600&interation=&interV=kKIOkrELjb8TkKIMkLELjbkRmLkElbYTkKIKmbELjboJmLkEk78TkKILkY==_-1167014467&htdbg=idc%3Egdylj%7CdbgID%3E01%7Cabt%3E7%7Cmth%3E1&ie=utf8&ref=360
http://www.sogou.com/sogou?query=%E4%BB%80%E4%B9%88%E5%8F%AB%E6%A0%91%E5%A5%97%E6%A0%91&pid=sogou-clse-60a70bb05b08d6cd
http://www.sogou.com/tx?query=%E7%BA%BF%E6%AE%B5%E6%A0%91%E5%A5%97%E5%B9%B3%E8%A1%A1%E6%A0%91&ie=utf8&_ast=1491659264&_asf=null&w=01029901&hdq=sogou-clse-a495eebbfa243b79-0001&duppid=1&cid=&sut=5029&sst0=1491659383886&lkt=0%2C0%2C0&sugsuv=00E601EC791FCD1758E8C284B93A4997&sugtime=1491659383886
http://blog.csdn.net/Sunshine_cfbsl/article/details/52184562?locationNum=1&fps=1
http://tieba.baidu.com/p/2152061053
#include<cstdio>
#define maxn 1000
int son[maxn][maxn],father[maxn],key[maxn],mi[maxn],mx[maxn],size[maxn];//son[x][0]=y表示节点x的左儿子是y;
int n,m,tip=0,num=0;
bool flag(int now)
{return son[father[now]][1]==now;}//左儿子返回零,右儿子返回一
void updata(int pos)
{size[pos]=size[son[pos][0]]+size[son[pos][1]]+1;}
void rotate(int now)//rotate now是指将now绕father rotate。有两个方向,表示now是father的左儿子还是右儿子。
{
int fa=father[now],fx=flag(now);//儿子编号
son[fa][fx]=son[now][!fx];
if(son[now][!fx])
father[son[now][!fx]]=fa; //连接father和son[now][!fx]
son[father[fa]][flag(fa)]=now;
father[now]=father[fa]; //连接grandpa和now
son[now][!fx]=fa;
father[fa]=now; //连接now和father
updata(fa);updata(now);//rotate完成后要updata
}
void splay(int now,int root)//通过方向标记,将两个方向的rotate合成一个。
{
while(father[now]!=root)
{
if(father[father[now]]!=root)
if(flag(now)==flag(father[now]))rotate(father[now]);
else rotate(now);
rotate(now);
}
}
int kth(int now,int th)//寻找k小值的标号
{
if(size[son[now][0]]+1==th)return now;
else if(size[son[now][0]]+1>th)return kth(son[now][0],th);
else return kth(son[now][1],th-size[son[now][0]]-1);
}
int pre(int val)//寻找前驱
{
int tmp=kth(son[val][0],size[son[val][0]]);
splay(tmp,val);
return key[tmp];
}
int succ(int val)//寻找后继
{
int tmp=kth(son[val][1],1);
splay(tmp,val);
return key[tmp];
}
int getpos(int now,int val)//找到一个合适的位置插入
{
if((key[now]<val)&&(size[son[now][1]]))return getpos(son[now][1],val);
else if((key[now]>val)&&(size[son[now][0]]))return getpos(son[now][0],val);
return now;
}
void insert(int root,int pos,int val)//并不能保证这个点是大于还是小于插入节点
{
int sroot=father[root];
splay(root=getpos(root,val),sroot);
if(key[root]<val)
{
succ(root);//十分重要!!!!
rotate(root=son[root][1]);
}
int tmp=son[root][0];key[pos]=val;
son[root][0]=pos;father[pos]=root;
son[pos][0]=tmp;father[tmp]=pos;
updata(pos);updata(root);
splay(pos,0);
}
//我们把刚好比插入点大的点作为根,在左子树插入。
//如果根小于插入点,则要将根的[后继]变成根(注意不是根的右儿子!!!)
//至此splay的基本操作我们都完成了。
//对于有重复元素的题,就得特殊处理一下。
//find的时候必须找最小序号的哪一个,pre和succ查询的数可能不在splay中,要做一点处理。
void dele(int root,int val)//删除
{
int sroot=father[root];
splay(root=find(root,val),sroot);
if(son[root][1])splay(succ(root),root);
son[sroot][flag(root)]=son[root][1];
father[son[root][1]]=sroot;
son[son[root][1]][0]=son[root][0];
father[son[root][0]]=son[root][1];
updata(son[root][1]);
}
int rank(int now,int val)//查找标号
{
if(key[now]==val)return size[son[now][0]]+1;
else if(val<key[now])return rank(son[now][0],val);
else if(val>key[now])return size[son[now][0]]+1+rank(son[now][1],val);
}
int find(int now,int val)//另外一个查找
{//pos
if(mx[son[now][0]]>=val)return find(son[now][0],val);
if(key[now]==val)return now;
if(mi[son[now][1]]<=val)return find(son[now][1],val);
return now;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 10000
int n,root,son[maxn][2],fa[maxn],weight[maxn];
int askflag(int x)
{if(son[fa[x]][0]==x) return 0;return 1;}
void updata(int x)
{
while(1)
{
weight[x]=weight[son[x][0]]+weight[son[x][1]];
if(x==root) break;
x=fa[x];
}
}
void rorate(int now)
{
int flag1=askflag(now),f2=askflag(fa[now]),father=fa[now],grandpa=fa[fa[now]];
fa[now]=grandpa;
son[grandpa][f2]=now;
fa[son[now][(flag1+1)%2]]=father;
son[father][flag1]=son[now][(flag1+1)%2];
son[now][(flag1+1)%2]=father;
fa[father]=now;
updata(now);updata(father);
}
void splay(int now,int root)
{
while(now!=root)
{
if(fa[now]!=root)
if(askflag(fa[now])!=flag(now))rorate(fa[now]);
else rorate(now);
rorate(now);
}
}
int main()
{
}