分類: 資料結構
2013-09-07 20:12
300人閱讀收藏
舉報題目:
題意:給出每個點的兩個值key和fix,且所有的key值和fix值都是不相同的,要求構造出笛卡爾樹。輸入每個點的兩個權
值,輸出笛卡爾樹每個結點(按照輸入的順序編號)的父親結點和兩個兒子的編號。
分析:首先,笛卡爾樹對於key來說是二叉搜尋樹,對於fix來說是最小堆,所以跟treap一樣。
笛卡爾樹在lca和rmq問題中有
著重要的應用。這題首先記錄下每個結點的id,然後以key為關鍵字排序。排完了之後就會有線性的構造笛卡爾樹的演算法了。
這裡的笛卡爾樹一定是存在的,所以先輸出yes。
構造笛卡爾樹的過程:
使用資料結構棧,棧中儲存的始終是右鏈,即根結點、根結點的右兒子、根結點的右兒子的右兒子……組成的鏈,並且棧中從
棧頂到棧底key依次減小。
如果按照從後到前的順序判斷乙個元素是否大於a[i],則每次插入的時間複雜度為o(k+1),k為本次插入中移除的右鏈元素個
數。因為每個元素最多進出右鏈各一次,所以整個過程的時間複雜度為o(n)。
[cpp]view plain
copy
#include
#include
#include
#include
using
namespace
std;
const
intn=1000005;
const
intinf=~0u>>1;
struct
node
bool
operator < (node t)
const
};
node t[n];
intstack[n],p[n],top;
void
init(
intn)
intbuild(
intn)
else
} return
stack[1];
} int
main()
sort(t+1,t+n+1);
introot=build(n);
for(
inti=1; i<=n; i++)
p[t[i].id]=i;
puts("yes"
);
for(
inti=1; i<=n; i++)
printf("%d %d %d\n"
,t[t[p[i]].pre].id,t[t[p[i]].l].id,t[t[p[i]].r].id);
return
0;
}
pat笛卡爾樹
笛卡爾樹是一種特殊的二叉樹,其結點包含兩個關鍵字k1和k2。首先笛卡爾樹是關於k1的二叉搜尋樹,即結點左子樹的所有k1值都比該結點的k1值小,右子樹則大。其次所有結點的k2關鍵字滿足優先佇列 不妨設為最小堆 的順序要求,即該結點的k2值比其子樹中所有結點的k2值小。給定一棵二叉樹,請判斷該樹是否笛卡...
笛卡爾樹小結
粗略的學習了一下笛卡爾樹 主要是為了平衡樹打基礎吧 因為關於平衡樹 treap 早忘了 splay 不信任複雜度 然後 我能學一種比較簡單的樹y 笛卡爾樹.這裡以建出小根堆為例。描述區間性質的樹 可以當成二叉搜尋樹不過並不平衡因為每次都是選取當前區間最小值當做為根 然後顯然根據區間的數的排列不同樹的...
笛卡爾樹學習筆記
笛卡爾樹學習筆記 笛卡爾樹是一種二叉樹,每乙個結點由乙個鍵值二元組 k,w 構成。要求 k 滿足二叉搜尋樹的性質,而 w 滿足堆的性質。乙個有趣的事實是,如果笛卡爾樹的 k,w 鍵值確定,且 k 互不相同,w 互不相同,那麼這個笛卡爾樹的結構是唯一的 在一般情況下,未說明 k 時,我們預設 k 為下...