int[] gather(int k, int maxRow) 返回长度为 2 的数组,表示 k 个成员中 第一个座位 的排数和座位编号,这 k 位成员必须坐在 同一排座位,且座位连续 。换言之,返回最小可能的 r 和 c 满足第 r 排中 [c, c + k - 1] 的座位都是空的,且 r <= maxRow 。如果 无法 安排座位,返回 [] 。
boolean scatter(int k, int maxRow) 如果组里所有 k 个成员 不一定 要坐在一起的前提下,都能在第 0 排到第 maxRow 排之间找到座位,那么请返回 true 。这种情况下,每个成员都优先找排数 最小 ,然后是座位编号最小的座位。如果不能安排所有 k 个成员的座位,请返回 false 。
classNode:__slots__="l","r","s","mx"def__init__(self):self.l=self.r=0self.s=self.mx=0classSegmentTree:def__init__(self,n,m):self.m=mself.tr=[Node()for_inrange(n<<2)]self.build(1,1,n)defbuild(self,u,l,r):self.tr[u].l,self.tr[u].r=l,rifl==r:self.tr[u].s=self.tr[u].mx=self.mreturnmid=(l+r)>>1self.build(u<<1,l,mid)self.build(u<<1|1,mid+1,r)self.pushup(u)defmodify(self,u,x,v):ifself.tr[u].l==xandself.tr[u].r==x:self.tr[u].s=self.tr[u].mx=vreturnmid=(self.tr[u].l+self.tr[u].r)>>1ifx<=mid:self.modify(u<<1,x,v)else:self.modify(u<<1|1,x,v)self.pushup(u)defquery_sum(self,u,l,r):ifself.tr[u].l>=landself.tr[u].r<=r:returnself.tr[u].smid=(self.tr[u].l+self.tr[u].r)>>1v=0ifl<=mid:v+=self.query_sum(u<<1,l,r)ifr>mid:v+=self.query_sum(u<<1|1,l,r)returnvdefquery_idx(self,u,l,r,k):ifself.tr[u].mx<k:return0ifself.tr[u].l==self.tr[u].r:returnself.tr[u].lmid=(self.tr[u].l+self.tr[u].r)>>1ifself.tr[u<<1].mx>=k:returnself.query_idx(u<<1,l,r,k)ifr>mid:returnself.query_idx(u<<1|1,l,r,k)return0defpushup(self,u):self.tr[u].s=self.tr[u<<1].s+self.tr[u<<1|1].sself.tr[u].mx=max(self.tr[u<<1].mx,self.tr[u<<1|1].mx)classBookMyShow:def__init__(self,n:int,m:int):self.n=nself.tree=SegmentTree(n,m)defgather(self,k:int,maxRow:int)->List[int]:maxRow+=1i=self.tree.query_idx(1,1,maxRow,k)ifi==0:return[]s=self.tree.query_sum(1,i,i)self.tree.modify(1,i,s-k)return[i-1,self.tree.m-s]defscatter(self,k:int,maxRow:int)->bool:maxRow+=1ifself.tree.query_sum(1,1,maxRow)<k:returnFalsei=self.tree.query_idx(1,1,maxRow,1)forjinrange(i,self.n+1):s=self.tree.query_sum(1,j,j)ifs>=k:self.tree.modify(1,j,s-k)returnTruek-=sself.tree.modify(1,j,0)returnTrue# Your BookMyShow object will be instantiated and called as such:# obj = BookMyShow(n, m)# param_1 = obj.gather(k,maxRow)# param_2 = obj.scatter(k,maxRow)
classNode{intl,r;longmx,s;}classSegmentTree{privateNode[]tr;privateintm;publicSegmentTree(intn,intm){this.m=m;tr=newNode[n<<2];for(inti=0;i<tr.length;++i){tr[i]=newNode();}build(1,1,n);}privatevoidbuild(intu,intl,intr){tr[u].l=l;tr[u].r=r;if(l==r){tr[u].s=m;tr[u].mx=m;return;}intmid=(l+r)>>1;build(u<<1,l,mid);build(u<<1|1,mid+1,r);pushup(u);}publicvoidmodify(intu,intx,longv){if(tr[u].l==x&&tr[u].r==x){tr[u].s=v;tr[u].mx=v;return;}intmid=(tr[u].l+tr[u].r)>>1;if(x<=mid){modify(u<<1,x,v);}else{modify(u<<1|1,x,v);}pushup(u);}publiclongquerySum(intu,intl,intr){if(tr[u].l>=l&&tr[u].r<=r){returntr[u].s;}intmid=(tr[u].l+tr[u].r)>>1;longv=0;if(l<=mid){v+=querySum(u<<1,l,r);}if(r>mid){v+=querySum(u<<1|1,l,r);}returnv;}publicintqueryIdx(intu,intl,intr,intk){if(tr[u].mx<k){return0;}if(tr[u].l==tr[u].r){returntr[u].l;}intmid=(tr[u].l+tr[u].r)>>1;if(tr[u<<1].mx>=k){returnqueryIdx(u<<1,l,r,k);}if(r>mid){returnqueryIdx(u<<1|1,l,r,k);}return0;}privatevoidpushup(intu){tr[u].s=tr[u<<1].s+tr[u<<1|1].s;tr[u].mx=Math.max(tr[u<<1].mx,tr[u<<1|1].mx);}}classBookMyShow{privateintn;privateintm;privateSegmentTreetree;publicBookMyShow(intn,intm){this.n=n;this.m=m;tree=newSegmentTree(n,m);}publicint[]gather(intk,intmaxRow){++maxRow;inti=tree.queryIdx(1,1,maxRow,k);if(i==0){returnnewint[]{};}longs=tree.querySum(1,i,i);tree.modify(1,i,s-k);returnnewint[]{i-1,(int)(m-s)};}publicbooleanscatter(intk,intmaxRow){++maxRow;if(tree.querySum(1,1,maxRow)<k){returnfalse;}inti=tree.queryIdx(1,1,maxRow,1);for(intj=i;j<=n;++j){longs=tree.querySum(1,j,j);if(s>=k){tree.modify(1,j,s-k);returntrue;}k-=s;tree.modify(1,j,0);}returntrue;}}/** * Your BookMyShow object will be instantiated and called as such: * BookMyShow obj = new BookMyShow(n, m); * int[] param_1 = obj.gather(k,maxRow); * boolean param_2 = obj.scatter(k,maxRow); */
classNode{public:intl,r;longs,mx;};classSegmentTree{public:SegmentTree(intn,intm){this->m=m;tr.resize(n<<2);for(inti=0;i<n<<2;++i){tr[i]=newNode();}build(1,1,n);}voidmodify(intu,intx,intv){if(tr[u]->l==x&&tr[u]->r==x){tr[u]->s=tr[u]->mx=v;return;}intmid=(tr[u]->l+tr[u]->r)>>1;if(x<=mid){modify(u<<1,x,v);}else{modify(u<<1|1,x,v);}pushup(u);}longquerySum(intu,intl,intr){if(tr[u]->l>=l&&tr[u]->r<=r){returntr[u]->s;}intmid=(tr[u]->l+tr[u]->r)>>1;longv=0;if(l<=mid){v+=querySum(u<<1,l,r);}if(r>mid){v+=querySum(u<<1|1,l,r);}returnv;}intqueryIdx(intu,intl,intr,intk){if(tr[u]->mx<k){return0;}if(tr[u]->l==tr[u]->r){returntr[u]->l;}intmid=(tr[u]->l+tr[u]->r)>>1;if(tr[u<<1]->mx>=k){returnqueryIdx(u<<1,l,r,k);}if(r>mid){returnqueryIdx(u<<1|1,l,r,k);}return0;}private:vector<Node*>tr;intm;voidbuild(intu,intl,intr){tr[u]->l=l;tr[u]->r=r;if(l==r){tr[u]->s=m;tr[u]->mx=m;return;}intmid=(l+r)>>1;build(u<<1,l,mid);build(u<<1|1,mid+1,r);pushup(u);}voidpushup(intu){tr[u]->s=tr[u<<1]->s+tr[u<<1|1]->s;tr[u]->mx=max(tr[u<<1]->mx,tr[u<<1|1]->mx);}};classBookMyShow{public:BookMyShow(intn,intm){this->n=n;this->m=m;tree=newSegmentTree(n,m);}vector<int>gather(intk,intmaxRow){++maxRow;inti=tree->queryIdx(1,1,maxRow,k);if(i==0){return{};}longs=tree->querySum(1,i,i);tree->modify(1,i,s-k);return{i-1,(int)(m-s)};}boolscatter(intk,intmaxRow){++maxRow;if(tree->querySum(1,1,maxRow)<k){returnfalse;}inti=tree->queryIdx(1,1,maxRow,1);for(intj=i;j<=n;++j){longs=tree->querySum(1,j,j);if(s>=k){tree->modify(1,j,s-k);returntrue;}k-=s;tree->modify(1,j,0);}returntrue;}private:SegmentTree*tree;intm,n;};/** * Your BookMyShow object will be instantiated and called as such: * BookMyShow* obj = new BookMyShow(n, m); * vector<int> param_1 = obj->gather(k,maxRow); * bool param_2 = obj->scatter(k,maxRow); */
typeBookMyShowstruct{n,minttree*segmentTree}funcConstructor(nint,mint)BookMyShow{returnBookMyShow{n,m,newSegmentTree(n,m)}}func(this*BookMyShow)Gather(kint,maxRowint)[]int{maxRow++i:=this.tree.queryIdx(1,1,maxRow,k)ifi==0{return[]int{}}s:=this.tree.querySum(1,i,i)this.tree.modify(1,i,s-k)return[]int{i-1,this.m-s}}func(this*BookMyShow)Scatter(kint,maxRowint)bool{maxRow++ifthis.tree.querySum(1,1,maxRow)<k{returnfalse}i:=this.tree.queryIdx(1,1,maxRow,1)forj:=i;j<=this.n;j++{s:=this.tree.querySum(1,j,j)ifs>=k{this.tree.modify(1,j,s-k)returntrue}k-=sthis.tree.modify(1,j,0)}returntrue}typenodestruct{l,r,s,mxint}typesegmentTreestruct{tr[]*nodemint}funcnewSegmentTree(n,mint)*segmentTree{tr:=make([]*node,n<<2)fori:=rangetr{tr[i]=&node{}}t:=&segmentTree{tr,m}t.build(1,1,n)returnt}func(t*segmentTree)build(u,l,rint){t.tr[u].l,t.tr[u].r=l,rifl==r{t.tr[u].s,t.tr[u].mx=t.m,t.mreturn}mid:=(l+r)>>1t.build(u<<1,l,mid)t.build(u<<1|1,mid+1,r)t.pushup(u)}func(t*segmentTree)modify(u,x,vint){ift.tr[u].l==x&&t.tr[u].r==x{t.tr[u].s,t.tr[u].mx=v,vreturn}mid:=(t.tr[u].l+t.tr[u].r)>>1ifx<=mid{t.modify(u<<1,x,v)}else{t.modify(u<<1|1,x,v)}t.pushup(u)}func(t*segmentTree)querySum(u,l,rint)int{ift.tr[u].l>=l&&t.tr[u].r<=r{returnt.tr[u].s}mid:=(t.tr[u].l+t.tr[u].r)>>1v:=0ifl<=mid{v=t.querySum(u<<1,l,r)}ifr>mid{v+=t.querySum(u<<1|1,l,r)}returnv}func(t*segmentTree)queryIdx(u,l,r,kint)int{ift.tr[u].mx<k{return0}ift.tr[u].l==t.tr[u].r{returnt.tr[u].l}mid:=(t.tr[u].l+t.tr[u].r)>>1ift.tr[u<<1].mx>=k{returnt.queryIdx(u<<1,l,r,k)}ifr>mid{returnt.queryIdx(u<<1|1,l,r,k)}return0}func(t*segmentTree)pushup(uint){t.tr[u].s=t.tr[u<<1].s+t.tr[u<<1|1].st.tr[u].mx=max(t.tr[u<<1].mx,t.tr[u<<1|1].mx)}/** * Your BookMyShow object will be instantiated and called as such: * obj := Constructor(n, m); * param_1 := obj.Gather(k,maxRow); * param_2 := obj.Scatter(k,maxRow); */