#include #include using namespace std; const int N_SIZE = 500010; const int DO_NOT_EXIST = -1; const int NOT_GIVEN = 0; int n; int pre_order[N_SIZE]; int post_order[N_SIZE]; int in_order[N_SIZE]; int index_in_pre_order[N_SIZE]; int index_in_post_order[N_SIZE]; int index_in_in_order[N_SIZE]; int parent[N_SIZE]; int left_child[N_SIZE]; int right_child[N_SIZE]; int single_child[N_SIZE]; int generated_inorder[N_SIZE]; int inorder_index; bool swing_left[N_SIZE]; int quantity; void construct_tree(int pre_order_start, int pre_order_end, int post_order_start, int post_order_end) { assert(pre_order_end - pre_order_start == post_order_end - post_order_start); int root = pre_order[pre_order_start]; if (pre_order_start == pre_order_end) { left_child[root] = DO_NOT_EXIST; right_child[root] = DO_NOT_EXIST; single_child[root] = DO_NOT_EXIST; return; } assert(pre_order_start + 1 <= n); assert(post_order_end - 1 >= 1); if (pre_order[pre_order_start + 1] == post_order[post_order_end - 1]) { left_child[root] = DO_NOT_EXIST; right_child[root] = DO_NOT_EXIST; single_child[root] = pre_order[pre_order_start + 1]; parent[single_child[root]] = root; construct_tree(pre_order_start + 1, pre_order_end, post_order_start, post_order_end - 1); return; } left_child[root] = pre_order[pre_order_start + 1]; int left_subtree_length = index_in_post_order[left_child[root]] - post_order_start + 1; right_child[root] = pre_order[pre_order_start + left_subtree_length + 1]; single_child[root] = DO_NOT_EXIST; parent[left_child[root]] = root; parent[right_child[root]] = root; construct_tree(pre_order_start + 1, pre_order_start + left_subtree_length, post_order_start, post_order_start + left_subtree_length - 1); construct_tree(pre_order_start + left_subtree_length + 1, pre_order_end, post_order_start + left_subtree_length, post_order_end - 1); } void compare_inorder() { assert(inorder_index == n); for (int i = 1; i <= n; i++) { assert(generated_inorder[i] > 0); if (in_order[i] != NOT_GIVEN && in_order[i] != generated_inorder[i]) { return; } } quantity++; } void get_inorder(int node) { if (left_child[node] == DO_NOT_EXIST && right_child[node] == DO_NOT_EXIST && single_child[node] == DO_NOT_EXIST ) { inorder_index++; generated_inorder[inorder_index] = node; } else if (single_child[node] == DO_NOT_EXIST) { get_inorder(left_child[node]); inorder_index++; generated_inorder[inorder_index] = node; get_inorder(right_child[node]); } else { if (swing_left[node]) { get_inorder(single_child[node]); inorder_index++; generated_inorder[inorder_index] = node; } else { inorder_index++; generated_inorder[inorder_index] = node; get_inorder(single_child[node]); } } } void dfs_swing(int index) { if (index > n) { inorder_index = 0; get_inorder(pre_order[1]); compare_inorder(); return; } if (single_child[index] != DO_NOT_EXIST) { swing_left[index] = true; dfs_swing(index + 1); swing_left[index] = false; dfs_swing(index + 1); } else { dfs_swing(index + 1); } } int main() { cin>>n; for (int i = 1; i <= n; i++) { cin>>pre_order[i]; index_in_pre_order[pre_order[i]] = i; } for (int i = 1; i <= n; i++) { cin>>post_order[i]; index_in_post_order[post_order[i]] = i; } for (int i = 1; i <= n; i++) { cin>>in_order[i]; index_in_in_order[in_order[i]] = i; } construct_tree(1, n, 1, n); quantity = 0; dfs_swing(1); cout<