Scapegoat_Tree模板和splay模板
来源:互联网 发布:2016淘宝买家可以贷款 编辑:程序博客网 时间:2024/06/06 05:38
#define N (100000+10)const double alpha=0.75;struct Node{ Node *ch[2]; int key,size,cover;// size为有效节点的数量,cover为节点总数量 bool exist;// 是否存在(即是否被删除) void push_up() { size=ch[0]->size+ch[1]->size+(int)exist; cover=ch[0]->cover+ch[1]->cover+1; } bool isBad() { return ((ch[0]->cover>cover*alpha+5)||(ch[1]->cover>cover*alpha+5)); }};struct Scapegoat_Tree{ Node mem_poor[N];//内存池,直接分配好避免动态分配内存占用时间 Node *tail,*root,*null;// 用null表示NULL的指针更方便,tail为内存分配指针,root为根 Node *bc[N];// 储存被删除的节点的内存地址,分配时可以再利用这些地址 int bc_top; Node *New_Node(int key) { Node *p=bc_top?bc[--bc_top]:tail++; p->ch[0]=p->ch[1]=null; p->size=p->cover=1,p->exist=true; p->key=key; return p; } void Travel(Node *p,vector<Node*>&v) { if (p==null) return; Travel(p->ch[0],v); if (p->exist) v.push_back(p); else bc[bc_top++]=p; Travel(p->ch[1],v); } Node *Divide(vector<Node*>&v,int l,int r) { if (l>=r) return null; int mid=l+r>>1; Node *p=v[mid]; p->ch[0]=Divide(v,l,mid); p->ch[1]=Divide(v,mid+1,r); p->push_up();// 自底向上维护,先维护子树 return p; } void Rebuild(Node *&p) { static vector <Node*>v; v.clear(); Travel(p,v); p=Divide(v,0,v.size()); } Node **Insert(Node *&p,int val) { if (p==null) { p=New_Node(val); return &null; } else { p->size++; p->cover++; // 返回值储存需要重构的位置,若子树也需要重构,本节点开始也需要重构,以本节点为根重构 Node **res=Insert(p->ch[val>=p->key],val); if (p->isBad()) res=&p; return res; } } void Erase(Node *p,int id) { p->size--; int offset=p->ch[0]->size+p->exist; if (p->exist&&id==offset) { p->exist=false; return; } else { if (id<=offset) Erase(p->ch[0],id); else Erase(p->ch[1],id-offset); } } void Init() { tail=mem_poor; null=tail++; null->ch[0]=null->ch[1]=null; null->cover=null->size=null->key=0; root=null; bc_top=0; } void Insert(int val) { Node **p=Insert(root,val); if (*p!=null) Rebuild(*p); } int Rank(int val) { Node *now=root; int ans=1; while (now!=null) { // 非递归求排名 if (now->key>=val) now=now->ch[0]; else { ans+=now->ch[0]->size+now->exist; now=now->ch[1]; } } return ans; } int Kth(int k) { Node *now=root; while (now!=null) { // 非递归求第K大 if (now->ch[0]->size+1==k&&now->exist) return now->key; else if (now->ch[0]->size>=k) now=now->ch[0]; else k-=now->ch[0]->size+now->exist,now=now->ch[1]; } } void Erase(int k) { Erase(root,Rank(k)); if (root->size<alpha*root->cover) Rebuild(root); } void Erase_kth(int k) { Erase(root, k); if (root->size<alpha*root->cover) Rebuild(root); }}stree;
struct Node{ int key,sz,cnt; int ch[2],pnt; Node(){} Node(int x,int y,int z) { key=x,sz=y,cnt=z; }}a[N<<1];int root,ncnt;void rs(int x){ a[x].sz=a[a[x].ch[0]].sz+a[a[x].ch[1]].sz+a[x].cnt;}void rotate(int x,bool d){ int y=a[x].pnt; a[y].ch[!d]=a[x].ch[d]; if (a[x].ch[d]!=0) a[a[x].ch[d]].pnt=y; a[x].pnt=a[y].pnt; if (a[y].pnt!=0) { if (y==a[a[y].pnt].ch[d]) a[a[y].pnt].ch[d]=x; else a[a[y].pnt].ch[!d]=x; } a[x].ch[d]=y; a[y].pnt=x; rs(y); rs(x);}void splay(int x,int target){ int y; while (a[x].pnt!=target) { y=a[x].pnt; if (x==a[y].ch[0]) { if (a[y].pnt!=target&&y==a[a[y].pnt].ch[0])rotate(y,true); rotate(x,true); } else { if (a[y].pnt!=target&&y==a[a[y].pnt].ch[1])rotate(y,false); rotate(x,false); } } if (target==0) root=x;}void Insert(int key,int now,int number){ if (root==0) { root=now?now:(++ncnt); a[root].ch[0]=a[root].ch[1]=a[root].pnt=0; a[root].key=key; a[root].sz=a[root].cnt=number; return; } int x=root,y; while (1) { a[x].sz+=number; if (key==a[x].key) { a[x].cnt+=number; a[x].sz+=number; rs(x); y=x; break; } else if (key<a[x].key) { if (a[x].ch[0]!=0) x=a[x].ch[0]; else { a[x].ch[0]=now?now:(++ncnt); y=a[x].ch[0]; a[y].key=key; a[y].sz=a[y].cnt=number; a[y].ch[0]=a[y].ch[1]=0; a[y].pnt=x; break; } } else { if (a[x].ch[1]!=0) x=a[x].ch[1]; else { a[x].ch[1]=now?now:(++ncnt); y=a[x].ch[1]; a[y].key=key; a[y].sz=a[y].cnt=number; a[y].ch[0]=a[y].ch[1]=0; a[y].pnt=x; break; } } } splay(y,0);}int searchmin(int x){ int y=a[x].pnt; while (a[x].ch[0]!=0) x=a[x].ch[0]; splay(x,y); return x;}int search(int key){ if (root==0) return 0; int x=root,y=0; while (1) { if (key==a[x].key) break; else if (key>a[x].key) { if (a[x].ch[1]!=0) x=a[x].ch[1]; else break; } else { if (a[x].ch[0]!=0) x=a[x].ch[0]; else break; } } y=x; splay(x,0); return y;}int Erase(int key,int number){ if (root==0) return 0; int x=search(key),y; if (x==0) return 0; if (a[x].cnt>number) { a[x].cnt-=number; a[x].sz-=number; rs(x); return 0; } else if (a[x].ch[0]==0&&a[x].ch[1]==0) { root=0; return x; } else if (a[x].ch[0]==0) { root=a[x].ch[1]; a[a[x].ch[1]].pnt=0; return x; } else if (a[x].ch[1]==0) { root=a[x].ch[0]; a[a[x].ch[0]].pnt=0; return x; } y=searchmin(a[x].ch[1]); a[y].pnt=0; a[y].ch[0]=a[x].ch[0]; a[a[x].ch[0]].pnt=y; rs(y); root=y; return x;}int qry_kth(int x,int y){ int now=root; while (now) { if (a[a[now].ch[0]].sz>=x) now=a[now].ch[0]; else { if (a[a[now].ch[0]].sz+a[now].cnt<x){x-=a[a[now].ch[0]].sz+a[now].cnt;now=a[now].ch[1];} else break;} } return a[now].key;}
0 0
- Scapegoat_Tree模板和splay模板
- SPLAY模板
- (模板)splay
- splay模板
- splay 模板
- splay 模板
- 【模板】splay
- splay模板
- splay模板
- Splay模板
- Splay模板
- splay 模板
- Splay模板
- 【模板】Splay
- splay模板
- Splay模板
- Splay模板
- Splay模板
- 通过三次优化,我将gif加载优化了16.9%
- Hibernate4注解方法
- python中input和raw_input的区别
- 微信公众号开发申请服务器资源
- winhttp put
- Scapegoat_Tree模板和splay模板
- JAVA上传文件图片到指定服务器目录
- HDU 2073无限的路
- 杭电2410Baskets_Of_Gold_Coins
- 面试中遇到的问题
- Redis的基本配置
- Apache Cordova-Android框架原理研究笔记
- 【Eclipse导入项目】项目出现红叉解决办法
- SQL性能优化十条经验