#include #include #include #include using namespace std; struct node { int i; node* parent; bool ap, b; list children; bool isAP() const { return ap && parent && !parent->b; } bool isParent(node* p) { return p == this || parent && parent->isParent(p); } int visible() { int cnt = 0; for (node* p = this; p && !p->b; p = p->parent) { if (!p->isAP()) { if (p != this) cnt++; cnt += p->ccount(this); } } return cnt; } int ccount(node* asking) { int cnt = 0; for (node* c : children) { if (!c->b) { if (c->isAP()) { cnt += c->ccount(asking); } else { if (!asking->isParent(c)) cnt++; } } } return cnt; } }; struct solution { int N, Q; vector nodes; vector QT; vector QI; void read(istream& is) { is >> N >> Q; nodes.resize(N); for (int i = 0; i < N; i++) { int n; is >> n; nodes[i].i = i + 1; if (n) { nodes[i].parent = &nodes[n - 1]; nodes[n - 1].children.push_back(&nodes[i]); } } QT.resize(Q); QI.resize(Q); for (int i = 0; i < Q; i++) is >> QT[i] >> QI[i]; } void write(ostream& os) { for (int i = 0; i < Q; i++) { int ni = QI[i] - 1; node& n = nodes[ni]; switch (QT[i]) { case 'C': os << n.visible() << endl; break; case 'T': n.ap = !n.ap; break; case 'B': n.b = !n.b; for (node* c : n.children) c->ap = false; break; } } } }; int main() { solution s; ifstream is("visibility.in"); s.read(is); ofstream os("visibility.out"); s.write(os); }