不得不打的splay模板,忘得实在太多了
平衡树是很常用的,但splay的代码实在忘得太多,考场上时间紧没有时间推,所以平时记住比较好。
只上精简版的。
#include<cstdio> #include<string.h> #include<algorithm> #include<cmath> #define N 110000 using namespace std; struct spt_node { struct node { long l,r,fa,aug; node(){} node(long h1,long h2,long h3,long h4) { l=h1,r=h2,fa=h3,aug=h4; } }t[N]; long root,cnt; void rebuild() { root=1,cnt=0; } void rotate(long now,long aim){//(important) if (aim==0)root=now;//(important) while (t[now].fa!=0){ long fa=t[now].fa,ffa=t[fa].fa; t[now].fa=ffa,t[fa].fa=now; if (t[now].aug<t[fa].aug){//lson long temp=t[now].r; t[now].r=fa,t[fa].l=temp; } else {//rson long temp=t[now].l; t[now].l=fa,t[fa].r=temp; } if (ffa!=0) if (t[now].aug<t[ffa].aug)t[ffa].l=now;//lson else t[ffa].r=now;//rson } } void insert(long now,long aug) { if (cnt==0){//(important) cnt++,t[1]=node(0,0,0,aug); return; } long la; for (;now!=0;){ la=now; if (aug==t[now].aug)break;//same value else if (aug<t[now].aug)now=t[now].l; else now=t[now].r; } if (now!=0)return; t[++cnt]=node(0,0,la,aug); if (aug<t[la].aug)t[la].l=cnt; else t[la].r=cnt; rotate(cnt,0); } }spt1; int main() { return 0; }
总共只有三个函数:rebuild,rotate,insert,细节要特别注意不要打挂了。find操作跟普通树大同小异。至于区间删除,需要注意维护一个待用点队列(循环队列),其他因题而异。详情参考某splay模板。