classExamRoom:def__init__(self,n:int):defdist(x):l,r=xreturnr-l-1ifl==-1orr==nelse(r-l)>>1self.n=nself.ts=SortedList(key=lambdax:(-dist(x),x[0]))self.left={}self.right={}self.add((-1,n))defseat(self)->int:s=self.ts[0]p=(s[0]+s[1])>>1ifs[0]==-1:p=0elifs[1]==self.n:p=self.n-1self.delete(s)self.add((s[0],p))self.add((p,s[1]))returnpdefleave(self,p:int)->None:l,r=self.left[p],self.right[p]self.delete((l,p))self.delete((p,r))self.add((l,r))defadd(self,s):self.ts.add(s)self.left[s[1]]=s[0]self.right[s[0]]=s[1]defdelete(self,s):self.ts.remove(s)self.left.pop(s[1])self.right.pop(s[0])# Your ExamRoom object will be instantiated and called as such:# obj = ExamRoom(n)# param_1 = obj.seat()# obj.leave(p)
classExamRoom{privateTreeSet<int[]>ts=newTreeSet<>((a,b)->{intd1=dist(a),d2=dist(b);returnd1==d2?a[0]-b[0]:d2-d1;});privateMap<Integer,Integer>left=newHashMap<>();privateMap<Integer,Integer>right=newHashMap<>();privateintn;publicExamRoom(intn){this.n=n;add(newint[]{-1,n});}publicintseat(){int[]s=ts.first();intp=(s[0]+s[1])>>1;if(s[0]==-1){p=0;}elseif(s[1]==n){p=n-1;}del(s);add(newint[]{s[0],p});add(newint[]{p,s[1]});returnp;}publicvoidleave(intp){intl=left.get(p),r=right.get(p);del(newint[]{l,p});del(newint[]{p,r});add(newint[]{l,r});}privateintdist(int[]s){intl=s[0],r=s[1];returnl==-1||r==n?r-l-1:(r-l)>>1;}privatevoidadd(int[]s){ts.add(s);left.put(s[1],s[0]);right.put(s[0],s[1]);}privatevoiddel(int[]s){ts.remove(s);left.remove(s[1]);right.remove(s[0]);}}/** * Your ExamRoom object will be instantiated and called as such: * ExamRoom obj = new ExamRoom(n); * int param_1 = obj.seat(); * obj.leave(p); */
intN;intdist(constpair<int,int>&p){auto[l,r]=p;if(l==-1||r==N)returnr-l-1;return(r-l)>>1;}structcmp{booloperator()(constpair<int,int>&a,constpair<int,int>&b)const{intd1=dist(a),d2=dist(b);returnd1==d2?a.first<b.first:d1>d2;};};classExamRoom{public:ExamRoom(intn){N=n;this->n=n;add({-1,n});}intseat(){autos=*ts.begin();intp=(s.first+s.second)>>1;if(s.first==-1){p=0;}elseif(s.second==n){p=n-1;}del(s);add({s.first,p});add({p,s.second});returnp;}voidleave(intp){intl=left[p],r=right[p];del({l,p});del({p,r});add({l,r});}private:set<pair<int,int>,cmp>ts;unordered_map<int,int>left;unordered_map<int,int>right;intn;voidadd(pair<int,int>s){ts.insert(s);left[s.second]=s.first;right[s.first]=s.second;}voiddel(pair<int,int>s){ts.erase(s);left.erase(s.second);right.erase(s.first);}};/** * Your ExamRoom object will be instantiated and called as such: * ExamRoom* obj = new ExamRoom(n); * int param_1 = obj->seat(); * obj->leave(p); */
typeExamRoomstruct{rbt*redblacktree.Treeleftmap[int]intrightmap[int]intnint}funcConstructor(nint)ExamRoom{dist:=func(s[]int)int{ifs[0]==-1||s[1]==n{returns[1]-s[0]-1}return(s[1]-s[0])>>1}cmp:=func(a,bany)int{x,y:=a.([]int),b.([]int)d1,d2:=dist(x),dist(y)ifd1==d2{returnx[0]-y[0]}returnd2-d1}this:=ExamRoom{redblacktree.NewWith(cmp),map[int]int{},map[int]int{},n}this.add([]int{-1,n})returnthis}func(this*ExamRoom)Seat()int{s:=this.rbt.Left().Key.([]int)p:=(s[0]+s[1])>>1ifs[0]==-1{p=0}elseifs[1]==this.n{p=this.n-1}this.del(s)this.add([]int{s[0],p})this.add([]int{p,s[1]})returnp}func(this*ExamRoom)Leave(pint){l,_:=this.left[p]r,_:=this.right[p]this.del([]int{l,p})this.del([]int{p,r})this.add([]int{l,r})}func(this*ExamRoom)add(s[]int){this.rbt.Put(s,struct{}{})this.left[s[1]]=s[0]this.right[s[0]]=s[1]}func(this*ExamRoom)del(s[]int){this.rbt.Remove(s)delete(this.left,s[1])delete(this.right,s[0])}/** * Your ExamRoom object will be instantiated and called as such: * obj := Constructor(n); * param_1 := obj.Seat(); * obj.Leave(p); */
classExamRoom{privatets:TreeSet<number[]>=newTreeSet<number[]>((a,b)=>{constd1=this.dist(a),d2=this.dist(b);returnd1===d2?a[0]-b[0]:d2-d1;});privateleft:Map<number,number>=newMap();privateright:Map<number,number>=newMap();privaten:number;constructor(n:number){this.n=n;this.add([-1,n]);}seat():number{consts=this.ts.first();letp=Math.floor((s[0]+s[1])/2);if(s[0]===-1){p=0;}elseif(s[1]===this.n){p=this.n-1;}this.del(s);this.add([s[0],p]);this.add([p,s[1]]);returnp;}leave(p:number):void{constl=this.left.get(p)!;constr=this.right.get(p)!;this.del([l,p]);this.del([p,r]);this.add([l,r]);}privatedist(s:number[]):number{const[l,r]=s;returnl===-1||r===this.n?r-l-1:Math.floor((r-l)/2);}privateadd(s:number[]):void{this.ts.add(s);this.left.set(s[1],s[0]);this.right.set(s[0],s[1]);}privatedel(s:number[]):void{this.ts.delete(s);this.left.delete(s[1]);this.right.delete(s[0]);}}typeCompare<T>=(lhs:T,rhs:T)=>number;classRBTreeNode<T=number>{data:T;count:number;left:RBTreeNode<T>|null;right:RBTreeNode<T>|null;parent:RBTreeNode<T>|null;color:number;constructor(data:T){this.data=data;this.left=this.right=this.parent=null;this.color=0;this.count=1;}sibling():RBTreeNode<T>|null{if(!this.parent)returnnull;// sibling null if no parentreturnthis.isOnLeft()?this.parent.right:this.parent.left;}isOnLeft():boolean{returnthis===this.parent!.left;}hasRedChild():boolean{return(Boolean(this.left&&this.left.color===0)||Boolean(this.right&&this.right.color===0));}}classRBTree<T>{root:RBTreeNode<T>|null;lt:(l:T,r:T)=>boolean;constructor(compare:Compare<T>=(l:T,r:T)=>(l<r?-1:l>r?1:0)){this.root=null;this.lt=(l:T,r:T)=>compare(l,r)<0;}rotateLeft(pt:RBTreeNode<T>):void{constright=pt.right!;pt.right=right.left;if(pt.right)pt.right.parent=pt;right.parent=pt.parent;if(!pt.parent)this.root=right;elseif(pt===pt.parent.left)pt.parent.left=right;elsept.parent.right=right;right.left=pt;pt.parent=right;}rotateRight(pt:RBTreeNode<T>):void{constleft=pt.left!;pt.left=left.right;if(pt.left)pt.left.parent=pt;left.parent=pt.parent;if(!pt.parent)this.root=left;elseif(pt===pt.parent.left)pt.parent.left=left;elsept.parent.right=left;left.right=pt;pt.parent=left;}swapColor(p1:RBTreeNode<T>,p2:RBTreeNode<T>):void{consttmp=p1.color;p1.color=p2.color;p2.color=tmp;}swapData(p1:RBTreeNode<T>,p2:RBTreeNode<T>):void{consttmp=p1.data;p1.data=p2.data;p2.data=tmp;}fixAfterInsert(pt:RBTreeNode<T>):void{letparent=null;letgrandParent=null;while(pt!==this.root&&pt.color!==1&&pt.parent?.color===0){parent=pt.parent;grandParent=pt.parent.parent;/* Case : A Parent of pt is left child of Grand-parent of pt */if(parent===grandParent?.left){constuncle=grandParent.right;/* Case : 1 The uncle of pt is also red Only Recoloring required */if(uncle&&uncle.color===0){grandParent.color=0;parent.color=1;uncle.color=1;pt=grandParent;}else{/* Case : 2 pt is right child of its parent Left-rotation required */if(pt===parent.right){this.rotateLeft(parent);pt=parent;parent=pt.parent;}/* Case : 3 pt is left child of its parent Right-rotation required */this.rotateRight(grandParent);this.swapColor(parent!,grandParent);pt=parent!;}}else{/* Case : B Parent of pt is right child of Grand-parent of pt */constuncle=grandParent!.left;/* Case : 1 The uncle of pt is also red Only Recoloring required */if(uncle!=null&&uncle.color===0){grandParent!.color=0;parent.color=1;uncle.color=1;pt=grandParent!;}else{/* Case : 2 pt is left child of its parent Right-rotation required */if(pt===parent.left){this.rotateRight(parent);pt=parent;parent=pt.parent;}/* Case : 3 pt is right child of its parent Left-rotation required */this.rotateLeft(grandParent!);this.swapColor(parent!,grandParent!);pt=parent!;}}}this.root!.color=1;}delete(val:T):boolean{constnode=this.find(val);if(!node)returnfalse;node.count--;if(!node.count)this.deleteNode(node);returntrue;}deleteAll(val:T):boolean{constnode=this.find(val);if(!node)returnfalse;this.deleteNode(node);returntrue;}deleteNode(v:RBTreeNode<T>):void{constu=BSTreplace(v);// True when u and v are both blackconstuvBlack=(u===null||u.color===1)&&v.color===1;constparent=v.parent!;if(!u){// u is null therefore v is leafif(v===this.root)this.root=null;// v is root, making root nullelse{if(uvBlack){// u and v both black// v is leaf, fix double black at vthis.fixDoubleBlack(v);}else{// u or v is redif(v.sibling()){// sibling is not null, make it red"v.sibling()!.color=0;}}// delete v from the treeif(v.isOnLeft())parent.left=null;elseparent.right=null;}return;}if(!v.left||!v.right){// v has 1 childif(v===this.root){// v is root, assign the value of u to v, and delete uv.data=u.data;v.left=v.right=null;}else{// Detach v from tree and move u upif(v.isOnLeft())parent.left=u;elseparent.right=u;u.parent=parent;if(uvBlack)this.fixDoubleBlack(u);// u and v both black, fix double black at uelseu.color=1;// u or v red, color u black}return;}// v has 2 children, swap data with successor and recursethis.swapData(u,v);this.deleteNode(u);// find node that replaces a deleted node in BSTfunctionBSTreplace(x:RBTreeNode<T>):RBTreeNode<T>|null{// when node have 2 childrenif(x.left&&x.right)returnsuccessor(x.right);// when leafif(!x.left&&!x.right)returnnull;// when single childreturnx.left??x.right;}// find node that do not have a left child// in the subtree of the given nodefunctionsuccessor(x:RBTreeNode<T>):RBTreeNode<T>{lettemp=x;while(temp.left)temp=temp.left;returntemp;}}fixDoubleBlack(x:RBTreeNode<T>):void{if(x===this.root)return;// Reached rootconstsibling=x.sibling();constparent=x.parent!;if(!sibling){// No sibiling, double black pushed upthis.fixDoubleBlack(parent);}else{if(sibling.color===0){// Sibling redparent.color=0;sibling.color=1;if(sibling.isOnLeft())this.rotateRight(parent);// left caseelsethis.rotateLeft(parent);// right casethis.fixDoubleBlack(x);}else{// Sibling blackif(sibling.hasRedChild()){// at least 1 red childrenif(sibling.left&&sibling.left.color===0){if(sibling.isOnLeft()){// left leftsibling.left.color=sibling.color;sibling.color=parent.color;this.rotateRight(parent);}else{// right leftsibling.left.color=parent.color;this.rotateRight(sibling);this.rotateLeft(parent);}}else{if(sibling.isOnLeft()){// left rightsibling.right!.color=parent.color;this.rotateLeft(sibling);this.rotateRight(parent);}else{// right rightsibling.right!.color=sibling.color;sibling.color=parent.color;this.rotateLeft(parent);}}parent.color=1;}else{// 2 black childrensibling.color=0;if(parent.color===1)this.fixDoubleBlack(parent);elseparent.color=1;}}}}insert(data:T):boolean{// search for a position to insertletparent=this.root;while(parent){if(this.lt(data,parent.data)){if(!parent.left)break;elseparent=parent.left;}elseif(this.lt(parent.data,data)){if(!parent.right)break;elseparent=parent.right;}elsebreak;}// insert node into parentconstnode=newRBTreeNode(data);if(!parent)this.root=node;elseif(this.lt(node.data,parent.data))parent.left=node;elseif(this.lt(parent.data,node.data))parent.right=node;else{parent.count++;returnfalse;}node.parent=parent;this.fixAfterInsert(node);returntrue;}find(data:T):RBTreeNode<T>|null{letp=this.root;while(p){if(this.lt(data,p.data)){p=p.left;}elseif(this.lt(p.data,data)){p=p.right;}elsebreak;}returnp??null;}*inOrder(root:RBTreeNode<T>=this.root!):Generator<T,undefined,void>{if(!root)return;for(constvofthis.inOrder(root.left!))yieldv;yieldroot.data;for(constvofthis.inOrder(root.right!))yieldv;}*reverseInOrder(root:RBTreeNode<T>=this.root!):Generator<T,undefined,void>{if(!root)return;for(constvofthis.reverseInOrder(root.right!))yieldv;yieldroot.data;for(constvofthis.reverseInOrder(root.left!))yieldv;}}classTreeSet<T=number>{_size:number;tree:RBTree<T>;compare:Compare<T>;constructor(collection:T[]|Compare<T>=[],compare:Compare<T>=(l:T,r:T)=>(l<r?-1:l>r?1:0),){if(typeofcollection==='function'){compare=collection;collection=[];}this._size=0;this.compare=compare;this.tree=newRBTree(compare);for(constvalofcollection)this.add(val);}size():number{returnthis._size;}has(val:T):boolean{return!!this.tree.find(val);}add(val:T):boolean{constsuccessful=this.tree.insert(val);this._size+=successful?1:0;returnsuccessful;}delete(val:T):boolean{constdeleted=this.tree.deleteAll(val);this._size-=deleted?1:0;returndeleted;}ceil(val:T):T|undefined{letp=this.tree.root;lethigher=null;while(p){if(this.compare(p.data,val)>=0){higher=p;p=p.left;}else{p=p.right;}}returnhigher?.data;}floor(val:T):T|undefined{letp=this.tree.root;letlower=null;while(p){if(this.compare(val,p.data)>=0){lower=p;p=p.right;}else{p=p.left;}}returnlower?.data;}higher(val:T):T|undefined{letp=this.tree.root;lethigher=null;while(p){if(this.compare(val,p.data)<0){higher=p;p=p.left;}else{p=p.right;}}returnhigher?.data;}lower(val:T):T|undefined{letp=this.tree.root;letlower=null;while(p){if(this.compare(p.data,val)<0){lower=p;p=p.right;}else{p=p.left;}}returnlower?.data;}first():T|undefined{returnthis.tree.inOrder().next().value;}last():T|undefined{returnthis.tree.reverseInOrder().next().value;}shift():T|undefined{constfirst=this.first();if(first===undefined)returnundefined;this.delete(first);returnfirst;}pop():T|undefined{constlast=this.last();if(last===undefined)returnundefined;this.delete(last);returnlast;}*[Symbol.iterator]():Generator<T,void,void>{for(constvalofthis.values())yieldval;}*keys():Generator<T,void,void>{for(constvalofthis.values())yieldval;}*values():Generator<T,undefined,void>{for(constvalofthis.tree.inOrder())yieldval;returnundefined;}/** * Return a generator for reverse order traversing the set */*rvalues():Generator<T,undefined,void>{for(constvalofthis.tree.reverseInOrder())yieldval;returnundefined;}}/** * Your ExamRoom object will be instantiated and called as such: * var obj = new ExamRoom(n) * var param_1 = obj.seat() * obj.leave(p) */