#include #include #include #include #include #include #include #include #include // #include // #include // template // using OSet = __gnu_pbds::tree , __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>; typedef long long llong; const int MAXN = 150000 + 10; const int INF = 1e9; int n, q; int sz; struct MergeSortTree // points in square { // OSet tree[4*MAXN]; struct Fenwick { std::vector tree; void build(int sz) { tree.resize(sz + 1, 0); } void update(int pos) { pos++; for (int idx = pos ; idx < tree.size() ; idx += idx & (-idx)) { tree[idx]++; } } int query(int pos) { pos++; int res = 0; for (int idx = pos ; idx > 0 ; idx -= idx & (-idx)) { res += tree[idx]; } return res; } }; Fenwick fenwick[4*MAXN]; std::vector values[4*MAXN]; void build(int l, int r, int node, int inB[]) { fenwick[node].build(r - l + 1); if (l == r) { values[node].push_back(inB[l]); return; } int mid = l + r >> 1; build(l, mid, 2*node, inB); build(mid + 1, r, 2*node + 1, inB); int lPtr = 0, rPtr = 0; values[node].reserve(r - l + 1); for (int i = l ; i <= r ; ++i) { if (lPtr == values[2 * node].size()) { values[node].push_back(values[2 * node + 1][rPtr++]); continue; } if (rPtr == values[2 * node + 1].size()) { values[node].push_back(values[2 * node][lPtr++]); continue; } if (values[2 * node][lPtr] < values[2 * node + 1][rPtr]) { values[node].push_back(values[2 * node][lPtr++]); } else { values[node].push_back(values[2 * node + 1][rPtr++]); } } } int findLast(int node, int value) { int l = -1, r = values[node].size(), mid; while (l < r - 1) { mid = l + r >> 1; if (values[node][mid] <= value) l = mid; else r = mid; } return l; } void update(int l, int r, int node, int queryPos, int queryVal) { fenwick[node].update(findLast(node, queryVal)); if (l == r) { return; } int mid = l + r >> 1; if (queryPos <= mid) update(l, mid, 2*node, queryPos, queryVal); else update(mid + 1, r, 2*node + 1, queryPos, queryVal); } int query(int l, int r, int node, int queryAL, int queryAR, int queryBL, int queryBR) { if (queryAL <= l && r <= queryAR) { return fenwick[node].query(findLast(node, queryBR)) - fenwick[node].query(findLast(node, queryBL - 1)); } int res = 0; int mid = l + r >> 1; if (queryAL <= mid) res += query(l, mid, 2*node, queryAL, queryAR, queryBL, queryBR); if (mid + 1 <= queryAR) res += query(mid + 1, r, 2*node + 1, queryAL, queryAR, queryBL, queryBR); return res; } void build(int inB[]) { build(1, sz, 1, inB); } void update(int inA, int inB) { update(1, sz, 1, inA, inB); } int query(int lA, int rA, int lB, int rB) { return query(1, sz, 1, lA, rA, lB, rB); } }; int timer; int inA[MAXN]; int inB[MAXN]; int outA[MAXN]; int outB[MAXN]; int respectiveB[MAXN]; std::vector a[MAXN]; std::vector b[MAXN]; std::queue > ask; std::queue > update; MergeSortTree tree; void dfsA(int node, int par) { inA[node] = ++timer; for (const int &u : a[node]) { if (u == par) { continue; } dfsA(u, node); } outA[node] = timer; } void dfsB(int node, int par) { inB[node] = ++timer; for (const int &u : b[node]) { if (u == par) { continue; } dfsB(u, node); } outB[node] = timer; } void solve() { dfsA(1, 0); timer = 0; dfsB(1, 0); for (int i = 1 ; i <= sz ; ++i) { respectiveB[inA[i]] = inB[i]; } tree.build(respectiveB); for (int i = 1 ; i <= n ; ++i) { tree.update(inA[i], inB[i]); } for (int i = 1 ; i <= q ; ++i) { if (update.front().second < ask.front().second) { int node = update.front().first; tree.update(inA[node], inB[node]); update.pop(); } else { int node = ask.front().first; std::cout << tree.query(inA[node], outA[node], 1, sz) - tree.query(inA[node], outA[node], inB[node], outB[node]) << '\n'; ask.pop(); } } } void input() { std::cin >> n; for (int i = 2 ; i <= n ; ++i) { int p; std::cin >> p; a[p].push_back(i); } for (int i = 2 ; i <= n ; ++i) { int p; std::cin >> p; b[p].push_back(i); } std::cin >> q; int counter = n; for (int i = 1 ; i <= q ; ++i) { int qType; std::cin >> qType; if (qType == 2) { int node; std::cin >> node; ask.push({node, i}); } else { int node, pA, pB; std::cin >> node >> pA >> pB; a[pA].push_back(node); b[pB].push_back(node); update.push({node, i}); counter++; } } sz = counter; ask.push({0, q + 1}); update.push({0, q + 1}); } void fastIOI() { freopen("company.in", "r", stdin); freopen("company.out", "w", stdout); std::ios_base :: sync_with_stdio(0); std::cout.tie(nullptr); std::cin.tie(nullptr); } int main() { fastIOI(); input(); solve(); return 0; }