静态建树有两种方法,一是每次找出根节点是什么,递归建树即可,二是假设原来的是空树,一个一个地插入去。 本题是后者, 先贴一下前者代码,超时了,但感觉此做法是对的 #include <cstdio> #include <algorithm> #include <cassert> using namespace std; const int MAX = 50010; typedef struct _Node { int k; int a; int index; }Node; typedef struct _Tree { int parent; int left; int right; }Tree; Node data[MAX]; Tree tree[MAX]; int getmin( int left , int right ) { int min = left; for( int i = left + 1 ; i <= right ; ++i ) if( data[i].a < data[min].a ) min = i ; return min; } void setchild( int parent , bool isleft , int value ) { if( isleft ) tree[ parent ].left = value; else tree[ parent ].right = value; } void createtree( int left , int right , int parent , bool isleft ) { if( left > right ) setchild( parent , isleft , 0 ); else if( left == right ) { tree[data[left].index].parent = parent; setchild( parent , isleft , data[left].index ); createtree( left , left - 1 , data[left].index , true ); createtree( left , left - 1 , data[left].index , false ); } else { int mid = getmin( left , right ); tree[ data[mid].index ].parent = parent; setchild( parent , isleft , data[mid].index ); createtree( left , mid - 1 , data[mid].index , true ); createtree( mid + 1 , right , data[mid].index , false ); } } bool cmp( const Node& left , const Node & right ) { return left.k < right.k ; } int main() { int n; scanf("%d",&n); for( int i = 1 ; i <= n ; ++i ) { scanf("%d%d",&data[i].k , &data[i].a ); data[i].index = i; } sort( &data[1] , &data[n+1] , cmp ); createtree( 1 , n , 0 , true ); printf("YES/n"); for( int i = 1 ; i <= n ; ++i ) printf("%d %d %d/n",tree[i].parent , tree[i].left , tree[i].right ); } 下面是后者的代码,时间为901ms #include <cstdio> #include <cstdlib> using namespace std; const int MAX = 50010; typedef struct _Node { int k , a , index; }Node; typedef struct _Tree { int parent , left , right ; }Tree; Node data[MAX]; Node stack[MAX]; Tree tree[MAX]; int cmp( const void* left , const void* right ) { Node* Left = ( Node* )left; Node* Right = ( Node * )right; return Left->k - Right->k; } int main() { int n , i , stacki; scanf("%d",&n); for( i = 1 ; i <= n ; ++i ) scanf("%d%d",&data[i].k , &data[i].a ) , data[i].index = i ; qsort( &data[1] , n , sizeof( Node ) , cmp ); stacki = -1; for( int j = 1 ; j <= n ; ++j ) { for( i = stacki ; i >= 0 && stack[i].a > data[j].a ; --i ) ; tree[ data[j].index ].parent = 0 ; tree[ data[j].index ].left = 0 ; tree[ data[j].index ].right = 0 ; if( i >= 0 ) { tree[ stack[i].index ].right = data[j].index; tree[ data[j].index ].parent = stack[i].index; } if( i + 1 <= stacki ) { tree[ stack[i+1].index ].parent = data[j].index ; tree[ data[j].index ].left = stack[i+1].index; } stacki = i + 1; stack[ stacki ] = data[j]; } printf("YES/n"); for( int i = 1 ; i <= n ; ++i ) { printf("%d %d %d/n",tree[i].parent , tree[i].left , tree[i].right ); } }