-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
code.cpp
140 lines (124 loc) · 3.7 KB
/
code.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright (c) 2020 Shivam Rathore. All rights reserved.
// Use of this source code is governed by MIT License that
// can be found in the LICENSE file.
// This file contains Solution to Challenge #024, run using
// g++ 001-050/024/c++/code.cpp -o bin/out
// ./bin/out < 001-050/024/c++/in.txt > 001-050/024/c++/out.txt
#include <bits/stdc++.h>
using namespace std;
#define ll long long
struct Node {
// val: value of node
int val;
// stats for locked nodes
bool state; // true for lock
int leftLocks; // no. of left sub-tree nodes that are locked
int rightLocks; // no. of right sub-tree nodes that are locked
Node *parent; // parent node
Node *left, *right; // children nodes
Node(Node *par, int v) {
parent = par;
val = v;
state = false;
leftLocks = rightLocks = 0;
left = right = NULL;
}
bool is_locked() { return state; }
bool lock() {
Node *tmp = this;
bool already = (state+leftLocks + rightLocks > 0);
while (tmp->parent && !already) {
tmp = tmp->parent;
already = tmp->state;
}
if (already) {
cout << "(already locked due to: " << tmp->val
<< " is_locked:" << (tmp->state ? "true" : "false")
<< " leftLocks:" << tmp->leftLocks
<< " rightLocks:" << tmp->rightLocks << ") ";
return false;
}
// the node or its parent are not locked, means the children are also
// not locked and the current node is free to be locked
state = true; // lock node
// set child lock for parents
tmp = this;
Node *par = tmp->parent;
while (par) {
if (par->left == tmp)
par->leftLocks++;
else
par->rightLocks++;
tmp = par;
par = par->parent;
}
return true;
}
bool unlock() {
if (!state) return false;
state = false; // unlock it
// update parent stats
Node *tmp = this, *par = tmp->parent;
while (par) {
if (par->left == tmp)
par->leftLocks--;
else
par->rightLocks--;
tmp = par;
par = par->parent;
}
return true;
}
};
void PrintTree(Node *root, string prefix) {
if (root->right != NULL) PrintTree(root->right, prefix + "\t");
cout << prefix << root->val << endl;
if (root->left != NULL) PrintTree(root->left, prefix + "\t");
}
void ScanTree(int n, Node **list) {
for (int i = 0; i < n; i++) {
list[i] = NULL;
}
n--;
while (n--) {
int x, y;
cin >> x >> y; // x is parent of y
if (list[x] == NULL) list[x] = new Node(NULL, x);
if (list[y] == NULL) list[y] = new Node(list[x], y);
list[y]->parent = list[x];
if (list[x]->left == NULL)
list[x]->left = list[y];
else
list[x]->right = list[y];
}
}
void solve() {
int n; // nodes
cin >> n;
Node *root, *list[n];
ScanTree(n, list);
// considering 0 as root
root = list[0];
PrintTree(root, "");
int q; // queries
cin >> q;
string op; // operation
int on; // on: node index
bool res; // response
while (q--) {
cin >> op >> on;
cout << op << " " << on << " ";
if (op == "lock")
res = list[on]->lock();
else if (op == "unlock")
res = list[on]->unlock();
else
res = list[on]->is_locked();
if (res)
cout << "true" << endl;
else
cout << "false" << endl;
}
return;
}
int main() { solve(); }