cogs2840. 二叉查找树
二叉查找樹(shù)
?
?
時(shí)間限制:1 s?? 內(nèi)存限制:512 MB
【題目描述】
?
二叉查找樹(shù)是一種特殊的二叉樹(shù)(每個(gè)節(jié)點(diǎn)最多只有兩個(gè)兒子的樹(shù))。樹(shù)的每個(gè)節(jié)點(diǎn)上存有一個(gè)唯一的值,并且滿足:這個(gè)節(jié)點(diǎn)的左子樹(shù)內(nèi)所有點(diǎn)的值都比這個(gè)節(jié)點(diǎn)的值小,且右子樹(shù)內(nèi)所有點(diǎn)的值都比這個(gè)節(jié)點(diǎn)的值要大。
對(duì)于一棵二叉查找樹(shù)T,我們可以將一個(gè)值為 x的新點(diǎn)插入 T中,且保持樹(shù)的性質(zhì)。算法如下:
需要將 x 插入樹(shù) T時(shí),執(zhí)行 insert(x,T.root)。
?
現(xiàn)在有 N 個(gè)數(shù)需要插入一棵空樹(shù)中。給定插入序列,請(qǐng)?jiān)诿總€(gè)元素被插入之后,輸出所有節(jié)點(diǎn)的深度總和(根的深度為 0)。
【輸入格式】
?
輸入的第一行一個(gè)整數(shù) n,表示序列長(zhǎng)度。
?
接下來(lái)一行n個(gè)數(shù)是序列中的數(shù)字,這些數(shù)字是各不相同的,在[1, n]區(qū)間。
【輸出格式】
?
?
輸出 n 行,第 i 行整數(shù)表示第 i個(gè)數(shù)插入樹(shù)后,至這個(gè)節(jié)點(diǎn)的節(jié)點(diǎn)深度總和。
?
?
【樣例輸入】
8 3 5 1 6 8 7 2 4【樣例輸出】
0 1 2 4 7 11 13 15【數(shù)據(jù)規(guī)模與約定】
?
對(duì)于 50%的數(shù)據(jù),滿足n ≤ 1000
對(duì)于100%的數(shù)據(jù),滿足n ≤ 3 ? 1e5
?
【來(lái)源】
qbxt 2017.10.7 t1
?
?
我們可以發(fā)現(xiàn),這棵二叉搜索樹(shù)構(gòu)建完畢之后,根節(jié)點(diǎn)總是比他的子樹(shù)內(nèi)任意一個(gè)節(jié)點(diǎn)先插入?,而直接構(gòu)造是n^2級(jí)別的,我們需要知道有一種東西叫笛卡爾樹(shù),其實(shí)就是一顆treap,既滿足二叉搜索樹(shù)的性質(zhì),又滿足堆的性質(zhì),對(duì)于任意一個(gè)節(jié)點(diǎn)有兩個(gè)值,key和fix,key滿足二叉搜索樹(shù),fix滿足堆,如果key是按大小順序插入的,那么我們可以在O(n)的時(shí)間內(nèi)構(gòu)造出這棵樹(shù),那么我們就按題目中所給數(shù)字大小順序插入,fix值為其插入時(shí)間,就可以構(gòu)造出符合題目的那棵樹(shù)了。(key和fix給定時(shí)可以唯一確定一棵樹(shù))
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?
轉(zhuǎn)載于:https://www.cnblogs.com/hyghb/p/8228287.html
總結(jié)
以上是生活随笔為你收集整理的cogs2840. 二叉查找树的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Mac idea中git igenore
- 下一篇: 1.2 - 列表练习题