Luogu P1377 [TJOI2011]树的序:离线nlogn建二叉搜索树

题目链接:https://www.luogu.org/problemnew/show/P1377

题意:

  有一棵n个节点的二叉搜索树。

  给出它的插入序列,是一个1到n的排列。

  问你使得树的形态相同的字典序最小的插入序列。

 

题解:

  由于插入序列为1到n的排列,所以一棵子树中的节点,一定是一段连续的整数。

  那么这棵子树的根,就是这段区间中,插入时间最早的那个数。

  O(NlogN)即可递归建树。

 

AC Code:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #define MAX_N 100005
 5 #define INF 1000000000
 6 
 7 using namespace std;
 8 
 9 int n;
10 int a[MAX_N];
11 int p[MAX_N];
12 int lson[MAX_N];
13 int rson[MAX_N];
14 
15 int find_root(int l,int r)
16 {
17     int t=INF,id=-1;
18     for(int i=l;i<=r;i++)
19     {
20         if(p[i]<t) t=p[i],id=i;
21     }
22     return id;
23 }
24 
25 int build(int l,int r)
26 {
27     if(l>r) return 0;
28     if(l==r) return l;
29     int rt=find_root(l,r);
30     lson[rt]=build(l,rt-1);
31     rson[rt]=build(rt+1,r);
32     return rt;
33 }
34 
35 void dfs(int x)
36 {
37     cout<<x<<" ";
38     if(lson[x]) dfs(lson[x]);
39     if(rson[x]) dfs(rson[x]);
40 }
41 
42 int main()
43 {
44     cin>>n;
45     for(int i=1;i<=n;i++)
46     {
47         cin>>a[i];
48         p[a[i]]=i;
49     }
50     memset(lson,0,sizeof(lson));
51     memset(rson,0,sizeof(rson));
52     dfs(build(1,n));
53 }

 

posted @ 2018-02-05 21:00  Leohh  阅读(166)  评论(0编辑  收藏  举报