classLockingTree:def__init__(self,parent:List[int]):n=len(parent)self.locked=[-1]*nself.parent=parentself.children=[[]for_inrange(n)]forson,fainenumerate(parent[1:],1):self.children[fa].append(son)deflock(self,num:int,user:int)->bool:ifself.locked[num]==-1:self.locked[num]=userreturnTruereturnFalsedefunlock(self,num:int,user:int)->bool:ifself.locked[num]==user:self.locked[num]=-1returnTruereturnFalsedefupgrade(self,num:int,user:int)->bool:defdfs(x:int):nonlocalfindforyinself.children[x]:ifself.locked[y]!=-1:self.locked[y]=-1find=Truedfs(y)x=numwhilex!=-1:ifself.locked[x]!=-1:returnFalsex=self.parent[x]find=Falsedfs(num)ifnotfind:returnFalseself.locked[num]=userreturnTrue# Your LockingTree object will be instantiated and called as such:# obj = LockingTree(parent)# param_1 = obj.lock(num,user)# param_2 = obj.unlock(num,user)# param_3 = obj.upgrade(num,user)
classLockingTree{privateint[]locked;privateint[]parent;privateList<Integer>[]children;publicLockingTree(int[]parent){intn=parent.length;locked=newint[n];this.parent=parent;children=newList[n];Arrays.fill(locked,-1);Arrays.setAll(children,i->newArrayList<>());for(inti=1;i<n;i++){children[parent[i]].add(i);}}publicbooleanlock(intnum,intuser){if(locked[num]==-1){locked[num]=user;returntrue;}returnfalse;}publicbooleanunlock(intnum,intuser){if(locked[num]==user){locked[num]=-1;returntrue;}returnfalse;}publicbooleanupgrade(intnum,intuser){intx=num;while(x!=-1){if(locked[x]!=-1){returnfalse;}x=parent[x];}boolean[]find=newboolean[1];dfs(num,find);if(!find[0]){returnfalse;}locked[num]=user;returntrue;}privatevoiddfs(intx,boolean[]find){for(inty:children[x]){if(locked[y]!=-1){locked[y]=-1;find[0]=true;}dfs(y,find);}}}/** * Your LockingTree object will be instantiated and called as such: * LockingTree obj = new LockingTree(parent); * boolean param_1 = obj.lock(num,user); * boolean param_2 = obj.unlock(num,user); * boolean param_3 = obj.upgrade(num,user); */
classLockingTree{public:LockingTree(vector<int>&parent){intn=parent.size();locked=vector<int>(n,-1);this->parent=parent;children.resize(n);for(inti=1;i<n;++i){children[parent[i]].push_back(i);}}boollock(intnum,intuser){if(locked[num]==-1){locked[num]=user;returntrue;}returnfalse;}boolunlock(intnum,intuser){if(locked[num]==user){locked[num]=-1;returntrue;}returnfalse;}boolupgrade(intnum,intuser){intx=num;while(x!=-1){if(locked[x]!=-1){returnfalse;}x=parent[x];}boolfind=false;function<void(int)>dfs=[&](intx){for(inty:children[x]){if(locked[y]!=-1){find=true;locked[y]=-1;}dfs(y);}};dfs(num);if(!find){returnfalse;}locked[num]=user;returntrue;}private:vector<int>locked;vector<int>parent;vector<vector<int>>children;};/** * Your LockingTree object will be instantiated and called as such: * LockingTree* obj = new LockingTree(parent); * bool param_1 = obj->lock(num,user); * bool param_2 = obj->unlock(num,user); * bool param_3 = obj->upgrade(num,user); */
typeLockingTreestruct{locked[]intparent[]intchildren[][]int}funcConstructor(parent[]int)LockingTree{n:=len(parent)locked:=make([]int,n)fori:=rangelocked{locked[i]=-1}children:=make([][]int,n)fori:=1;i<n;i++{children[parent[i]]=append(children[parent[i]],i)}returnLockingTree{locked,parent,children}}func(this*LockingTree)Lock(numint,userint)bool{ifthis.locked[num]==-1{this.locked[num]=userreturntrue}returnfalse}func(this*LockingTree)Unlock(numint,userint)bool{ifthis.locked[num]==user{this.locked[num]=-1returntrue}returnfalse}func(this*LockingTree)Upgrade(numint,userint)bool{x:=numfor;x!=-1;x=this.parent[x]{ifthis.locked[x]!=-1{returnfalse}}find:=falsevardfsfunc(int)dfs=func(xint){for_,y:=rangethis.children[x]{ifthis.locked[y]!=-1{find=truethis.locked[y]=-1}dfs(y)}}dfs(num)if!find{returnfalse}this.locked[num]=userreturntrue}/** * Your LockingTree object will be instantiated and called as such: * obj := Constructor(parent); * param_1 := obj.Lock(num,user); * param_2 := obj.Unlock(num,user); * param_3 := obj.Upgrade(num,user); */
classLockingTree{privatelocked:number[];privateparent:number[];privatechildren:number[][];constructor(parent:number[]){constn=parent.length;this.locked=Array(n).fill(-1);this.parent=parent;this.children=Array(n).fill(0).map(()=>[]);for(leti=1;i<n;i++){this.children[parent[i]].push(i);}}lock(num:number,user:number):boolean{if(this.locked[num]===-1){this.locked[num]=user;returntrue;}returnfalse;}unlock(num:number,user:number):boolean{if(this.locked[num]===user){this.locked[num]=-1;returntrue;}returnfalse;}upgrade(num:number,user:number):boolean{letx=num;for(;x!==-1;x=this.parent[x]){if(this.locked[x]!==-1){returnfalse;}}letfind=false;constdfs=(x:number)=>{for(constyofthis.children[x]){if(this.locked[y]!==-1){this.locked[y]=-1;find=true;}dfs(y);}};dfs(num);if(!find){returnfalse;}this.locked[num]=user;returntrue;}}/** * Your LockingTree object will be instantiated and called as such: * var obj = new LockingTree(parent) * var param_1 = obj.lock(num,user) * var param_2 = obj.unlock(num,user) * var param_3 = obj.upgrade(num,user) */