#include <bits/stdc++.h>
using namespace std;
template<class ElemType>
struct BiNode {
ElemType data;
BiNode<ElemType> *lchild, *rchild;
int disToLeft;
};
template<class ElemType>
class BiSortTree {
public:
BiSortTree(ElemType a[], int l, int r) {
root = new BiNode<ElemType>;
root = Create(a, l, r);
}
BiNode<ElemType> *Create(ElemType data[], int l, int r);
int InsertBST(BiNode<ElemType> *&BST, ElemType data);
int DeleteBST(BiNode<ElemType> *&BST, ElemType data);
BiNode<ElemType> *FindMinBST(BiNode<ElemType> *&BST);
BiNode<ElemType> *FindMaxBST(BiNode<ElemType> *&BST);
BiNode<ElemType> *FindBST(BiNode<ElemType> *&BST, ElemType data);
BiNode<ElemType> *FindPBST(BiNode<ElemType> *&BST, ElemType data);
int DepthBST(BiNode<ElemType> *&BST, ElemType data);
int Insert(ElemType data) {
return InsertBST(root, data);
}
int Delete(ElemType data) {
return DeleteBST(root, data);
}
BiNode<ElemType> *FindMin() {
return FindMinBST(root);
}
BiNode<ElemType> *FindMax() {
return FindMaxBST(root);
}
BiNode<ElemType> *Find(ElemType d) {
return FindBST(root, d);
}
BiNode<ElemType> *FindP(ElemType d) {
return FindPBST(root, d);
}
int Depth(ElemType d) {
return DepthBST(root, d);
}
~BiSortTree() {
Release(root);
}
void InOrder() {
InOrder(root);
}
BiNode<ElemType> *GetRoot() {
return root;
}
private:
BiNode<ElemType> *root;
void InOrder(BiNode<ElemType> *root);
void Release(BiNode<ElemType> *root);
};
template<class ElemType>
int BiSortTree<ElemType>::InsertBST(BiNode<ElemType> *&BST, ElemType data) {
if (!BST) {
BST = new BiNode<ElemType>;
BST->data = data;
BST->lchild = BST->rchild = NULL;
return 1;
} else {
if (data == BST->data) return 0;
if (data < BST->data) return InsertBST(BST->lchild, data);
else return InsertBST(BST->rchild, data);
}
}
template<class ElemType>
BiNode<ElemType> *BiSortTree<ElemType>::Create(ElemType data[], int l, int r) {
BiNode<ElemType> *bst = NULL;
for (int i = l; i <= r; i++)
if (InsertBST(bst, data[i]) == 0) {
cout << "
有重复元素,插入失败" << endl;
Release(bst);
return NULL;
}
return bst;
}
template<class ElemType>
void BiSortTree<ElemType>::Release(BiNode<ElemType> *root) {
if (root != NULL) {
Release(root->lchild);
Release(root->rchild);
delete root;
}
}
template<class ElemType>
void BiSortTree<ElemType>::InOrder(BiNode<ElemType> *root) {
if (root == NULL) return;
InOrder(root->lchild);
cout << root->data << " ";
InOrder(root->rchild);
}
template<class ElemType>
BiNode<ElemType> *BiSortTree<ElemType>::FindMinBST(BiNode<ElemType> *&BST) {
BiNode<ElemType> *cur = BST;
if (cur == NULL) return NULL;
while (cur) {
if (cur->lchild == NULL) return cur;
else cur = cur->lchild;
}
return NULL;
}
template<class ElemType>
BiNode<ElemType> *BiSortTree<ElemType>::FindMaxBST(BiNode<ElemType> *&BST) {
BiNode<ElemType> *cur = BST;
if (cur == NULL) return NULL;
while (cur) {
if (cur->rchild == NULL) return cur;
else cur = cur->rchild;
}
return NULL;
}
template<class ElemType>
BiNode<ElemType> *BiSortTree<ElemType>::FindBST(BiNode<ElemType> *&BST, ElemType data) {
BiNode<ElemType> *cur = BST;
if (cur == NULL) return NULL;
while (cur) {
if (cur->data == data) return cur;
else if (data < cur->data) cur = cur->lchild;
else cur = cur->rchild;
}
return NULL;
}
template<class ElemType>
BiNode<ElemType> *BiSortTree<ElemType>::FindPBST(BiNode<ElemType> *&BST, ElemType data) {
BiNode<ElemType> *cur = BST;
BiNode<ElemType> *last_cur = NULL;
if (cur == NULL) return NULL;
while (cur) {
if (cur->data == data) return last_cur;
else if (data < cur->data) {
last_cur = cur;
cur = cur->lchild;
} else {
last_cur = cur;
cur = cur->rchild;
}
}
return NULL;
}
template<class ElemType>
int BiSortTree<ElemType>::DepthBST(BiNode<ElemType> *&BST, ElemType data) {
BiNode<ElemType> *cur = BST;
int depth = 0;
if (cur == NULL) return -1;
while (cur) {
if (cur->data == data) return depth;
else if (data < cur->data) cur = cur->lchild;
else cur = cur->rchild;
depth++;
}
return -1;
}
template<class ElemType>
int BiSortTree<ElemType>::DeleteBST(BiNode<ElemType> *&BST, ElemType data) {
if (!BST) return 0;
else if (data < BST->data) return DeleteBST(BST->lchild, data);
else if (data > BST->data) return DeleteBST(BST->rchild, data);
else {
if (BST->lchild && BST->rchild) {
BiNode<ElemType> *tmp = FindMinBST(BST->rchild);
BST->data = tmp->data;
DeleteBST(BST->rchild, tmp->data);
} else {
BiNode<ElemType> *tmp = BST;
if (!BST->lchild) BST = BST->rchild;
else if (!BST->rchild) BST = BST->lchild;
delete tmp;
}
return 1;
}
}
int a[205], n, m;
vector<string> split(const string &str, const string &delim) {
vector<string> res;
if ("" == str) return res;
char *strs = new char[str.length() + 1];
strcpy(strs, str.c_str());
char *d = new char[delim.length() + 1];
strcpy(d, delim.c_str());
char *p = strtok(strs, d);
while (p) {
string s = p;
res.push_back(s);
p = strtok(NULL, d);
}
return res;
}
int main() {
cin >> n;
for (int i = 0; i < n; ++i) cin >> a[i];
BiSortTree<int> Bi(a, 0, n - 1);
cin >> m;
getchar();
while (m--) {
string s;
getline(cin, s);
vector<string> res = split(s, " ");
if (res[res.size() - 1] == "root") {
int A = atoi(res[0].c_str());
if (Bi.Find(A) == NULL) {
cout << "No" << endl;
continue;
}
if (A == Bi.GetRoot()->data) cout << "Yes" << endl;
else cout << "No" << endl;
} else if (res[res.size() - 1] == "siblings") {
int A = atoi(res[0].c_str());
int B = atoi(res[2].c_str());
if (Bi.Find(A) == NULL || Bi.Find(B) == NULL) {
cout << "No" << endl;
continue;
}
if (Bi.FindP(A)->data == Bi.FindP(B)->data)
cout << "Yes" << endl;
else cout << "No" << endl;
} else if (res[res.size() - 1] == "level") {
int A = atoi(res[0].c_str());
int B = atoi(res[2].c_str());
if (Bi.Find(A) == NULL || Bi.Find(B) == NULL) {
cout << "No" << endl;
continue;
}
if (Bi.Depth(A) == Bi.Depth(B)) cout << "Yes" << endl;
else cout << "No" << endl;
} else if (res[3] == "parent") {
int A = atoi(res[0].c_str());
int B = atoi(res[res.size() - 1].c_str());
if (Bi.Find(A) == NULL || Bi.Find(B) == NULL) {
cout << "No" << endl;
continue;
}
BiNode<int> *temp = Bi.FindP(B);
if (temp != NULL && temp->data == A) cout << "Yes" << endl;
else cout << "No" << endl;
} else if (res[3] == "left") {
int A = atoi(res[0].c_str());
int B = atoi(res[res.size() - 1].c_str());
if (Bi.Find(A) == NULL || Bi.Find(B) == NULL) {
cout << "No" << endl;
continue;
}
BiNode<int> *temp = Bi.Find(B);
if (temp->lchild != NULL && temp->lchild->data == A)
cout << "Yes" << endl;
else cout << "No" << endl;
} else if (res[3] == "right") {
int A = atoi(res[0].c_str());
int B = atoi(res[res.size() - 1].c_str());
if (Bi.Find(A) == NULL || Bi.Find(B) == NULL) {
cout << "No" << endl;
continue;
}
BiNode<int> *temp = Bi.Find(B);
if (temp->rchild != NULL && temp->rchild->data == A)
cout << "Yes" << endl;
else cout << "No" << endl;
}
}
return 0;
}