替罪羊树(指针板子)


#include<vector> using namespace std; namespace Scapegoat_Tree{ #define MAXN (100000 + 10) const double alpha = 0.75; struct Node{ Node * ch[2]; int key,size,cover; bool exist; void Pushup(void){ size=ch[0]->size+ch[1]->size+(int)exist; cover=ch[0]->cover+ch[1]->cover+1; } bool isBad(void){ return ((ch[0]->cover>cover*alpha+5)|| (ch[1]->cover>cover*alpha+5)); } }; struct STree{ protected: Node mem_poor[MAXN]; Node *tail,*root,*null; Node *bc[MAXN]; int bc_top; Node *NewNode(int key){ Node *p=bc_top?bc[--bc_top]:tail++; p->ch[0]=p->ch[1]=null; p->size=p->cover=1; p->key=key; p->exist=true; 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); p->Pushup(); return; } 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->Pushup(); return p; } void Rebuild(Node *&p){ static vector<Node *>v; v.clear();Travel(p,v); p=Divide(v,0,v.size()); return; } Node ** Insert(Node *&p,int val){ if(p==null){ p=NewNode(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); } } public: void Init(void){ tail=mem_poor; null=tail++; null->ch[0]=null->ch[1]=null; null->size=null->cover=null->key=0; null->exist=false; root=null;bc_top=0; return; } Stree(void){Init();} 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){ 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); } }; #undef MAXN } /* main() for luogu p3369 普通平衡树 : int main(void) { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); read(n); while (n--) { read(k), read(m); switch (k) { case 1: _t.Insert(m); break; case 2: _t.Erase(m); break; case 3: printf("%d\n", _t.Rank(m)); break; case 4: printf("%d\n", _t.Kth(m)); break; case 5: printf("%d\n", _t.Kth(_t.Rank(m) - 1)); break; case 6: printf("%d\n", _t.Kth(_t.Rank(m + 1))); break; } } return 0; } Outside of main: void read(int &x);//快读,略 using namespace Scapegoat_Tree; STree_t; int n,k,m; */

https://zhuanlan.zhihu.com/p/21263304

posted @ 2020-12-12 12:36  _Famiglistimo  阅读(115)  评论(0编辑  收藏  举报