func_code_string: #include <bits/stdc++.h>   const double EPS = 1e-8;   using namespace std;   long long gcd(long long a, long long b) {     if (b == 0) return a;     return gcd(b, a % b);   }   template <typename A, size_t N, typename T>   void Fill(A (&array)[N], const T &val) {     std::fill((T *)array, (T *)(array + N), val);   }   class Graph {    public:     int vn;     int sumcost = 0;     vector<vector<pair<int, int>>> g;     Graph(int n) {       vn = n;       g.resize(n);     }     virtual void con(int a, int b, int w) = 0;     int getWeight(int f, int t) {       auto itr = lower_bound((g[f]).begin(), (g[f]).end(), make_pair(t, INT_MIN));       if (itr != g[f].end()) return itr->second;       return INT_MIN;     }     int Costsum() { return sumcost; }     void scan(int edcount, bool oindexed, bool w) {       for (int i = (0); (edcount) > i; i++) {         int a, b, c = 1;         scanf( %d %d , &a, &b);         if (w) scanf( %d , &c);         con(a - oindexed, b - oindexed, c);       }     }   };   class BiDGraph : public Graph {    public:     BiDGraph(int n) : Graph(n) {}     void con(int a, int b, int w = 1) {       g[a].push_back({b, w});       g[b].push_back({a, w});       sumcost++;     }   };   struct RSQ {     int n;     vector<int> dat;     RSQ() {}     RSQ(int n_) {       n = 1;       while (n < n_) n *= 2;       dat.resize(2 * n - 1, 0);     }     void add(int k, int a) {       k += n - 1;       dat[k] += a;       while (k > 0) {         k = (k - 1) / 2;         dat[k] = dat[2 * k + 1] + dat[2 * k + 2];       }     }     int query(int a, int b) { return query(a, b, 0, 0, n); }     int query(int a, int b, int k, int l, int r) {       if (r <= a || b <= l) return 0;       if (a <= l && r <= b) return dat[k];       int vl = query(a, b, 2 * k + 1, l, (l + r) / 2);       int vr = query(a, b, 2 * k + 2, (l + r) / 2, r);       return vl + vr;     }   };   class Heavy_Light_Decomposition {    public:     BiDGraph g, compg;     vector<int> sz, depth, chain, par;     int bn = 0;     vector<int> bvn, inbn;     vector<vector<int>> bv;     Heavy_Light_Decomposition(BiDGraph graph, vector<int> root)         : g(graph),           compg(graph.vn),           sz(graph.vn, 1),           depth(graph.vn),           chain(graph.vn),           par(graph.vn),           bvn(graph.vn, -1),           inbn(graph.vn) {       for (auto itr : root) getsz(itr, itr);       bv.push_back(vector<int>());       for (auto itr : root) {         if (bv[bv.size() - 1].size()) bv.push_back(vector<int>()), bn++;         HLD(itr, -1, itr, bn);       }     }     int getsz(int cur, int p) {       par[cur] = p;       for (auto itr : g.g[cur])         if (p != itr.first)           depth[itr.first] = depth[cur] + 1, sz[cur] += getsz(itr.first, cur);       return sz[cur];     }     void HLD(int cur, int p, int head, int num) {       chain[cur] = head, bvn[cur] = num;       inbn[cur] = bv[num].size(), bv[num].push_back(cur);       pair<int, int> Maxc = {-1, -1};       for (auto itr : g.g[cur])         if (itr.first != p) Maxc = max(Maxc, {sz[itr.first], itr.first});       for (auto itr : g.g[cur])         if (itr.first != p) {           int nb = num;           if (itr.first != Maxc.second) {             bv.push_back(vector<int>());             nb = ++bn;           }           HLD(itr.first, cur, itr.first == Maxc.second ? head : itr.first, nb);         }     }     int lca(int a, int b) {       if (chain[a] == chain[b]) return depth[a] < depth[b] ? a : b;       if (depth[chain[a]] > depth[chain[b]]) return lca(par[chain[a]], b);       return lca(a, par[chain[b]]);     }     void for_each_edge(int a, int b, function<void(int, int)> func) {       if (chain[a] == chain[b])         return func(inbn[a] < inbn[b] ? a : b, inbn[a] < inbn[b] ? b : a);       if (depth[chain[a]] < depth[chain[b]]) swap(a, b);       for_each_edge(a, chain[a], func), for_each_edge(par[chain[a]], b, func);     }   };   struct UnionFind {     vector<int> data;     UnionFind(int size) : data(size, -1) {}     bool unionSet(int x, int y) {       x = root(x);       y = root(y);       if (x != y) {         if (data[y] < data[x]) swap(x, y);         data[x] += data[y];         data[y] = x;       }       return x != y;     }     bool findSet(int x, int y) { return root(x) == root(y); }     int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }     bool isroot(int x) { return data[x] < 0; }     int size(int x) { return -data[root(x)]; }   };   int main() {     int n;     cin >> n;     BiDGraph g(n);     vector<int> t(n);     vector<int> root;     UnionFind uf(n);     for (int i = (0); (n) > i; i++) {       int p;       scanf( %d %d , &p, &t[i]);       if (p == -1) root.push_back(i);       if (p > 0) uf.unionSet(i, p - 1), g.con(i, p - 1);     }     Heavy_Light_Decomposition hld(g, root);     vector<RSQ> seg;     for (int i = (0); (hld.bv.size()) > i; i++) {       seg.push_back(RSQ(hld.bv[i].size()));       for (int j = (0); (hld.bv[i].size()) > j; j++)         seg[i].add(j, t[hld.bv[i][j]]);     }     int q;     cin >> q;     for (int i = (0); (q) > i; i++) {       int mode, p, c;       scanf( %d %d %d , &mode, &p, &c);       c--, p--;       if (c == p || !uf.findSet(p, c)) {         printf( NO n );         continue;       }       int lca = hld.lca(p, c);       if (mode == 1) {         bool f = 0;         if (lca == p) {           int sum = 0;           hld.for_each_edge(p, c, [&](int u, int v) {             sum += seg[hld.bvn[u]].query(hld.inbn[u], hld.inbn[v] + 1);             if (u == lca) {               sum -= t[lca];             } else if (v == lca) {               sum -= t[lca];             }           });           if (sum == 0) f = 1;         }         printf(f ?  YES n  :  NO n );       } else {         if (lca == c) {           printf( NO n );           continue;         }         int sum = 0, sum2 = 0;         hld.for_each_edge(p, lca, [&](int u, int v) {           sum += seg[hld.bvn[u]].query(hld.inbn[u], hld.inbn[v] + 1);           if (u == lca) {             sum -= t[lca];           } else if (v == lca) {             sum -= t[lca];           }         });         hld.for_each_edge(c, lca, [&](int u, int v) {           sum2 += seg[hld.bvn[u]].query(hld.inbn[u], hld.inbn[v] + 1);           if (u == lca) {             sum2 -= t[lca];           } else if (v == lca) {             sum2 -= t[lca];           }         });         if (sum == 0 && sum2 == (hld.depth[c] - hld.depth[lca]))           printf( YES n );         else           printf( NO n );       }     }     return 0;   }   