Title:
Flute Karlshu: Each node in the Cartesian tree has two data domain K,a, for the data domain K, satisfies the binary search tree property, for data domain A, satisfies the minimum heap property.
Given N nodes, 1<=n<=50000, each node is composed of a pair of k,a, determine whether to build a Cartesian tree according to these nodes, if you can build the output constructed Cartesian tree, otherwise output "NO".
Problem Solving Ideas:
First, according to n nodes, a Cartesian tree can certainly be constructed.
Method 1:
Recursive (verified, the method will time out) (see Code 1.)
A) for the node array, select the node with the lowest value of a, the node is the root node
b) The node is divided by the K value of the root node, the nodes less than k are on the left side of the root node, the nodes greater than k are located on the right side of the root node.
c) The node on the left side of the root node is the node in the left subtree of the root node, the right node is the node in the right subtree, the node to the left of the root node is recursively constructed to the left subtree, and the node to the right of the root node is recursively constructed right sub-tree.
Method 2:
Node-by-insert method (see Code 2)
A) Sort the node array by the K value from small to large.
b) Make the first node the root node, iterate the array from the second node, and insert the nodes one by one into the tree
To insert a node into the tree, follow these steps:
Starting from the previous node of the current node to be inserted, a node is found at the bottom, so that the value of the node A is smaller than the value of the current node.
If not found:
The current node is the new root node, and the original root node is changed to the left child of the current node.
If you find:
The node labeled I is located, then I node the original right child is changed to the left child of the current node, the current node is the right child of node I.
c) Output results after insert is finished
Code Listing 1: Recursive method
#include <stdio.h> typedef struct {int K,a,num;//num numbering starting from 1} Node;
Node data[50000];
int father[50001];
int left_child[50001];
int right_child[50001];
int n;
/* Find the point in the data array, from subscript s to subscript e, to the smallest point of the secondary domain A, and return the dot in the array subscript */int Min_node (int s, int e) {int min_index,min_a;
Min_index=s;
MIN_A=DATA[S].A;
while (++s<=e) if (Data[s].a < min_a) {min_index=s;
MIN_A=DATA[S].A;
} return Min_index;
} Void Swap (node *a, node *b) {node temp;
temp = *a;
*a = *b;
*b = temp;
}//The element at index is the hub of the array, return the hub subscript int partition (int s, int e, int index) {int i,j;
Node Temp,pivot;
Swap hub element and start element Swap (&data[s], &data[index]);
k=1;
j=s+1;
Pivot=data[s];
while (j<=e) {if (Data[j].k < PIVOT.K) {i++;
Swap (&data[i], &data[j]);
} j + +;
} swap (&data[s], &data[i]);
return i; }/* Establishes a Cartesian tree for the data array subscript from S to e: start subscript, E: End subscript * Child: The root node of the currently constructed Cartesian tree is the parent node's children * P: The parent node number of the root node of the currently constructed Cartesian tree */void built (int s, int e, int child[], int p) {int Min_index, Pivot_index;
if (s>e) return;
Find the minimum node of the secondary domain A, which is the root node of the subtree Min_index=min_node (s,e);
Father[data[min_index].num]=p;
CHILD[P] = Data[min_index].num;
The array is divided by the K value of the root node Pivot_index = partition (S,e,min_index);
Build left subtree built (s, pivot_index-1, Left_child, data[pivot_index].num);
Build right subtree built (pivot_index+1, E, Right_child, data[pivot_index].num);
} int main () {int i;
scanf ("%d", &n);
for (i=0; i<n; i++) {scanf ("%d%d", &DATA[I].K, &DATA[I].A);
data[i].num=i+1; }//Build Cartesian tree built (0, n-1, left_child, 0);
The 3rd parameter is arbitrary, can also be right_child//print the result printf ("yes\n");
for (I=1; i<=n; i++) printf ("%d%d%d\n", Father[i], left_child[i], right_child[i]);
return 0;
}
Code Listing 2: inserting one by one
#include <stdio.h> typedef struct {int K,a,num;//num numbering starting from 1} Node;
Node data[50000];
int father[50001];
int left_child[50001];
int right_child[50001];
int convert[50001];
int n;
int cmp (const void *a, const void *b) {Node *p1,*p2;
P1= (node*) A;
P2= (node*) b;
Return p1->k-p2->k;
}//Inserts a node, index for the node in the data array subscript void Insert (int index) {int i,j;
I=data[index-1].num;
Locate the node with domain A smaller than the current node while (i!=0 && data[convert[i]].a > Data[index].a) {j=i;i=father[i];}
if (i==0) {//does not find such a node, the current node is the root node and the previous node is the left child of the current node father[j]=data[index].num;
Left_child[data[index].num] = j;
} else {//found such node I, then the right child of the current node is I, the original right child of I node is changed to the left child of the current node left_child[data[index].num]=right_child[i];
Father[right_child[i]]=data[index].num;
Right_child[i]=data[index].num;
Father[data[index].num]=i;
}} int main () {int i;
scanf ("%d", &n);
for (i=0; i<n; i++) {scanf ("%d%d", &DATA[I].K, &DATA[I].A);
data[i].num=i+1; }//To the node by a small to large sort qsort (data, N, sizEOF (Node), CMP);
The nodes are inserted into the tree convert[data[0].num]=0;
for (I=1; i<n; i++) convert[data[i].num]=i, insert (i);
Print the result printf ("yes\n");
for (I=1; i<=n; i++) printf ("%d%d%d\n", Father[i], left_child[i], right_child[i]);
return 0;
}