cogs2840. 二叉查找树
二叉查找樹
?
?
時間限制:1 s?? 內存限制:512 MB
【題目描述】
?
二叉查找樹是一種特殊的二叉樹(每個節(jié)點最多只有兩個兒子的樹)。樹的每個節(jié)點上存有一個唯一的值,并且滿足:這個節(jié)點的左子樹內所有點的值都比這個節(jié)點的值小,且右子樹內所有點的值都比這個節(jié)點的值要大。
對于一棵二叉查找樹T,我們可以將一個值為 x的新點插入 T中,且保持樹的性質。算法如下:
需要將 x 插入樹 T時,執(zhí)行 insert(x,T.root)。
?
現(xiàn)在有 N 個數(shù)需要插入一棵空樹中。給定插入序列,請在每個元素被插入之后,輸出所有節(jié)點的深度總和(根的深度為 0)。
【輸入格式】
?
輸入的第一行一個整數(shù) n,表示序列長度。
?
接下來一行n個數(shù)是序列中的數(shù)字,這些數(shù)字是各不相同的,在[1, n]區(qū)間。
【輸出格式】
?
?
輸出 n 行,第 i 行整數(shù)表示第 i個數(shù)插入樹后,至這個節(jié)點的節(jié)點深度總和。
?
?
【樣例輸入】
8 3 5 1 6 8 7 2 4【樣例輸出】
0 1 2 4 7 11 13 15【數(shù)據(jù)規(guī)模與約定】
?
對于 50%的數(shù)據(jù),滿足n ≤ 1000
對于100%的數(shù)據(jù),滿足n ≤ 3 ? 1e5
?
【來源】
qbxt 2017.10.7 t1
?
?
我們可以發(fā)現(xiàn),這棵二叉搜索樹構建完畢之后,根節(jié)點總是比他的子樹內任意一個節(jié)點先插入?,而直接構造是n^2級別的,我們需要知道有一種東西叫笛卡爾樹,其實就是一顆treap,既滿足二叉搜索樹的性質,又滿足堆的性質,對于任意一個節(jié)點有兩個值,key和fix,key滿足二叉搜索樹,fix滿足堆,如果key是按大小順序插入的,那么我們可以在O(n)的時間內構造出這棵樹,那么我們就按題目中所給數(shù)字大小順序插入,fix值為其插入時間,就可以構造出符合題目的那棵樹了。(key和fix給定時可以唯一確定一棵樹)
1 #include<cstdio> 2 #define ll long long 3 using namespace std; 4 const int inf=3e5+10; 5 int fix[inf],n,fa[inf],dep[inf],a[inf]; 6 ll ans; 7 int main() 8 { 9 scanf("%d",&n); 10 for(int i=1;i<=n;i++){ 11 scanf("%d",&a[i]); 12 fix[a[i]]=i; 13 } 14 for(int i=1;i<=n;i++){ 15 int last=0,f=i-1; 16 while(fix[f]>fix[i])last=f,f=fa[f]; 17 fa[i]=f; 18 fa[last]=i; 19 } 20 dep[0]=-1; 21 for(int i=1;i<=n;i++){ 22 dep[a[i]]=dep[fa[a[i]]]+1; 23 ans+=dep[a[i]]; 24 printf("%lld\n",ans); 25 } 26 return 0; 27 } View Code?
轉載于:https://www.cnblogs.com/hyghb/p/8228287.html
總結
以上是生活随笔為你收集整理的cogs2840. 二叉查找树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mac idea中git igenore
- 下一篇: 1.2 - 列表练习题