Skip to content

Commit 405ace0

Browse files
authored
Create operations-on-tree.cpp
1 parent 1c9a52f commit 405ace0

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

C++/operations-on-tree.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Time: ctor: O(n)
2+
// lock: O(1)
3+
// unlock: O(1)
4+
// upgrade: O(n)
5+
// Space: O(n)
6+
7+
class LockingTree {
8+
public:
9+
LockingTree(vector<int>& parent)
10+
: parent_(parent)
11+
, children_(size(parent)) {
12+
for (int i = 0; i < size(parent); ++i) {
13+
if (parent[i] != -1) {
14+
children_[parent_[i]].emplace_back(i);
15+
}
16+
}
17+
}
18+
19+
bool lock(int num, int user) {
20+
if (locked_.count(num)) {
21+
return false;
22+
}
23+
locked_[num] = user;
24+
return true;
25+
}
26+
27+
bool unlock(int num, int user) {
28+
if (!locked_.count(num) || locked_[num] != user) {
29+
return false;
30+
}
31+
locked_.erase(num);
32+
return true;
33+
}
34+
35+
bool upgrade(int num, int user) {
36+
for (int node = num; node != -1; node = parent_[node]) {
37+
if (locked_.count(node)) {
38+
return false;
39+
}
40+
}
41+
bool result = false;
42+
vector<int> stk = {num};
43+
while (!empty(stk)) {
44+
auto node = stk.back(); stk.pop_back();
45+
for (const auto& child : children_[node]) {
46+
if (locked_.count(child)) {
47+
locked_.erase(child);
48+
result = true;
49+
}
50+
stk.emplace_back(child);
51+
}
52+
}
53+
if (result) {
54+
locked_[num] = user;
55+
}
56+
return result;
57+
}
58+
59+
private:
60+
const vector<int>& parent_;
61+
vector<vector<int>> children_;
62+
unordered_map<int, int> locked_;
63+
};

0 commit comments

Comments
 (0)