A Sorted Cartesian tree is a tree of (key, priority) pairs. The tree is heap-ordered according to the priority values, and an inorder traversal gives the keys in sorted order. For example, given the pairs { (55, 8), (58, 15), (62, 3), (73, 4), (85, 1), (88, 5), (90, 12), (95, 10), (96, 18), (98, 6) }, the increasing min-heap Cartesian tree is shown by the figure.
Your job is to do level-order traversals on an increasing min-heap Cartesian tree.
Input Specification:
Each input file contains one test case. Each case starts from giving a positive integer
N
(
≤
30
)
N (≤30)
N(≤30), and then
N
N
N lines follow, each gives a pair in the format key priority
. All the numbers are in the range of int.
Output Specification:
For each test case, print in the first line the level-order traversal key sequence and then in the next line the level-order traversal priority sequence of the min-heap Cartesian tree.
All the numbers in a line must be separated by exactly one space, and there must be no extra space at the beginning or the end of the line.
Sample Input:
10
88 5
58 15
95 10
62 3
55 8
98 6
85 1
90 12
96 18
73 4
Sample Output:
85 62 88 55 73 98 58 95 90 96
1 3 5 8 4 6 15 10 12 18
Caution:
说实话拿到这道题我还是有点怵的,一个是因为这道树的题目竟然放到了第四题的位置,另外一个原因是这个数据结构以前从来没听说过(孤陋寡闻了),并且当时写这道题的时候状态也不是特别好(空调开得太冷了,当时肚子疼了一阵子),不过看清楚题目后规规矩矩写还是一遍 AC 了(虽然代码可能确实有些烂),题目其实不难,主要就是建树的过程和以往不太一样(不过姥姥这么安排确实有点考验心态的意思)。
Solution:
// Talk is cheap, show me the code
// Created by Misdirection 2021-09-11 14:28:36
// All rights reserved.
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <queue>
using namespace std;
struct Node{
int key;
int priority;
Node *left;
Node *right;
Node(int k, int p){
key = k;
priority = p;
left = NULL;
right = NULL;
}
~Node(){}
};
int n;
vector<Node> nodes;
vector<int> keyLevelOrder, priLevelOrder;
unordered_map<int, int> pri2Pos;
int pri[35];
Node *root;
unordered_map<int, bool> vis;
void findChildren(Node *r, int posInSorted, int leftEdge, int rightEdge){
if(r == NULL) return;
int left = -1, right = -1;
for(int i = posInSorted + 1; i < n; ++i){
if(vis[pri[i]]) continue;
if(left == -1 && nodes[pri2Pos[pri[i]]].key < r -> key && nodes[pri2Pos[pri[i]]].key > leftEdge){
left = i;
vis[pri[i]] = true;
continue;
}
else if(right == -1 && nodes[pri2Pos[pri[i]]].key > r -> key && nodes[pri2Pos[pri[i]]].key < rightEdge){
right = i;
vis[pri[i]] = true;
continue;
}
}
if(left != -1)
r -> left = new Node(nodes[pri2Pos[pri[left]]].key, nodes[pri2Pos[pri[left]]].priority);
if(right != -1)
r -> right = new Node(nodes[pri2Pos[pri[right]]].key, nodes[pri2Pos[pri[right]]].priority);
findChildren(r -> left, left, leftEdge, r -> key);
findChildren(r -> right, right, r -> key, rightEdge);
}
int main(){
scanf("%d", &n);
int k, p;
for(int i = 0; i < n; ++i){
scanf("%d %d", &k, &p);
nodes.emplace_back(k, p);
pri2Pos[p] = i;
pri[i] = p;
}
sort(pri, pri + n);
root = new Node(nodes[pri2Pos[pri[0]]].key, pri[0]);
findChildren(root, 0, -2147483648, 2147483647);
queue<Node*> q;
q.push(root);
while(!q.empty()){
if(q.front() -> left != NULL) q.push(q.front() -> left);
if(q.front() -> right != NULL) q.push(q.front() -> right);
keyLevelOrder.push_back(q.front() -> key);
priLevelOrder.push_back(q.front() -> priority);
q.pop();
}
for(int i = 0; i < n; ++i){
if(i == n - 1) printf("%d\n", keyLevelOrder[i]);
else printf("%d ", keyLevelOrder[i]);
}
for(int i = 0; i < n; ++i){
if(i == n - 1) printf("%d\n", priLevelOrder[i]);
else printf("%d ", priLevelOrder[i]);
}
return 0;
}