Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
Since the leaf values form a permutation of , the only strictly increasing final sequence is exactly . Also, the leaves of any fixed subtree always occupy one contiguous block in the global leaf order.
Therefore, every subtree must contain a consecutive interval of values. Let a successful subtree return that interval as . A leaf with value simply returns .
Suppose all children of an internal vertex already return valid intervals. Operations below this vertex arrange the contents of those intervals, while an operation at the vertex can only cyclically rotate their original order—not arbitrarily sort them.
The first child after the rotation is forced: it must be the child with the smallest left endpoint. Starting there and walking through the children cyclically, every consecutive pair must satisfy .
Process vertices bottom-up. If every cyclic boundary check passes, return the interval from the smallest left endpoint through the final right endpoint; otherwise answer NO. Finally require the root interval to be . Each child list is scanned only a constant number of times, so this is .
The crucial observation is that the target order is completely fixed. The positive leaf values form a permutation of , so a strictly increasing arrangement can only be
For any vertex , all leaves in the subtree of always appear consecutively in the left-to-right leaf traversal. Rotating children can move entire child subtrees around, but it cannot split one subtree and insert unrelated leaves into its middle.
Consequently, in the final sequence , the leaves belonging to any subtree must occupy consecutive positions. Their values must therefore form an integer interval.
This is stronger than merely asking whether that subtree's values can be sorted. For example, a subtree containing values and could locally produce , but it can never fit into the global sequence while value belongs to another subtree: that other leaf cannot be inserted between them.
For each vertex , we determine whether its subtree can become one valid consecutive block
If it can, we store the endpoints .
For a leaf containing , this is immediate:
Now consider an internal vertex whose children, in their original order, are
Assume their subtrees have already been checked and return valid intervals. Each child can internally produce its values in increasing order. What remains is arranging those child intervals.
Repeated left shifts do not allow an arbitrary permutation of the children. They allow only cyclic rotations:
So just sorting the child intervals would be cheating—the operation never gave us that superpower.
In a valid increasing concatenation, the first interval must be the one with the smallest left endpoint. Let its position in the original child list be . That forces the only potentially successful rotation: start at and then follow the children cyclically.
For the resulting blocks to join without a gap or inversion, every boundary must satisfy
If every boundary passes, their concatenation is exactly one consecutive interval. We set
There is deliberately no check from the last child back to the first. The output after choosing a rotation is a linear sequence, not some cursed circular permutation where must connect back to .
Intervals belonging to different children cannot overlap because all leaf values are distinct. Therefore the child with minimum is unique, and we can find it with a linear scan. No sorting is necessary.
We prove by induction over subtrees that the algorithm accepts a vertex exactly when its leaves can occupy one consecutive increasing block, and that the stored endpoints describe that block.
Base case. If is a leaf with value , its leaf sequence is already the one-element interval . The algorithm returns exactly that.
Necessity. Suppose an internal subtree rooted at can form a consecutive increasing block. Every child subtree occupies a contiguous part of that block, so each child must itself form a consecutive increasing interval. By the induction hypothesis, all children pass our checks.
The child blocks must appear in increasing interval order. Their first block is therefore the one with minimum left endpoint. Since the order of children can only be cyclically rotated, walking cyclically from that child must reproduce the increasing block order. Adjacent blocks in a consecutive interval have no missing value, so every checked equality must hold. Thus the algorithm accepts .
Sufficiency. Suppose every child passes and all boundary equalities pass when walking cyclically from the minimum-left child. By the induction hypothesis, arrange every child internally into its stored increasing interval. Rotate the children of so the minimum-left child comes first. The boundary equalities make these intervals concatenate into
Hence the subtree of forms a valid consecutive increasing block.
By induction, the invariant holds for every vertex. At the root, all leaves are included, so the required final sequence exists exactly when its interval is . Therefore the algorithm prints the correct answer.
The parent of a vertex may have a larger index, so processing vertices in decreasing numerical order is not valid. We first traverse from root to create an order in which every parent appears before its children, then process that order in reverse.
This also avoids recursive DFS: a chain of length is a pretty dumb reason to gamble on the call stack.
Every edge is scanned a constant number of times, giving:
The total over all test cases is at most .
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<vector<int>> children(n + 1);
for (int v = 2; v <= n; ++v) {
int p;
cin >> p;
children[p].push_back(v);
}
vector<int> a(n + 1);
int k = 0;
for (int v = 1; v <= n; ++v) {
cin >> a[v];
k += (a[v] > 0);
}
vector<int> order;
order.reserve(n);
order.push_back(1);
for (int i = 0; i < (int)order.size(); ++i) {
for (int v : children[order[i]]) {
order.push_back(v);
}
}
vector<int> lo(n + 1), hi(n + 1);
bool ok = true;
for (int it = (int)order.size() - 1; it >= 0 && ok; --it) {
int u = order[it];
if (children[u].empty()) {
lo[u] = hi[u] = a[u];
continue;
}
int d = (int)children[u].size();
int start = 0;
for (int i = 1; i < d; ++i) {
if (lo[children[u][i]] < lo[children[u][start]]) {
start = i;
}
}
int first = children[u][start];
lo[u] = lo[first];
hi[u] = hi[first];
for (int step = 1; step < d; ++step) {
int v = children[u][(start + step) % d];
if (hi[u] + 1 != lo[v]) {
ok = false;
break;
}
hi[u] = hi[v];
}
}
cout << (ok && lo[1] == 1 && hi[1] == k ? "YES\n" : "NO\n");
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<vector<int>> children(n + 1);
for (int v = 2; v <= n; ++v) {
int p;
cin >> p;
children[p].push_back(v);
}
vector<int> a(n + 1);
int k = 0;
for (int v = 1; v <= n; ++v) {
cin >> a[v];
k += (a[v] > 0);
}
vector<int> order;
order.reserve(n);
order.push_back(1);
for (int i = 0; i < (int)order.size(); ++i) {
for (int v : children[order[i]]) {
order.push_back(v);
}
}
vector<int> lo(n + 1), hi(n + 1);
bool ok = true;
for (int it = (int)order.size() - 1; it >= 0 && ok; --it) {
int u = order[it];
if (children[u].empty()) {
lo[u] = hi[u] = a[u];
continue;
}
int d = (int)children[u].size();
int start = 0;
for (int i = 1; i < d; ++i) {
if (lo[children[u][i]] < lo[children[u][start]]) {
start = i;
}
}
int first = children[u][start];
lo[u] = lo[first];
hi[u] = hi[first];
for (int step = 1; step < d; ++step) {
int v = children[u][(start + step) % d];
if (hi[u] + 1 != lo[v]) {
ok = false;
break;
}
hi[u] = hi[v];
}
}
cout << (ok && lo[1] == 1 && hi[1] == k ? "YES\n" : "NO\n");
}
return 0;
}