全域性平衡二叉樹學習筆記

2021-09-21 12:55:35 字數 1363 閱讀 6971

感覺是樹剖和lct的一種結合,把樹剖的log^2變成log,把lct的常數變小,但是能維護的東西也有侷限性...

實際上就是有時候維護的東西不需要lct的link-cut操作,所以可以將樹建成一棵棵二叉平衡樹連在一起而不需要splay。具體建法就是先輕重鏈剖分,對每條重鏈建一棵bst,然後這棵bst的根通過虛邊連向這棵bst內深度最淺的點在原樹中的父親。而對於每條重鏈建bst時,注意為了保證平衡,不是直接取中間的那個點,而是對重鏈上每個點賦乙個輕兒子子樹siz和的權值,找到帶權中心(使左右權值和盡可能相等的點),然後遞迴建樹。考慮一下複雜度:首先因為輕重鏈剖分,所以從一棵bst的根往上走一步樹的大小一定*2,在考慮我們對重鏈建的bst按輕兒子子樹大小建,這樣又可以保證在bst上往上走一步樹的大小也一定*2,所以這樣就保證這樣建的全域性平衡二叉樹樹高是log的。

資訊的維護基本就和lct維護區間資訊一樣,可以做一些動態dp之類的題目。

模板題:

這題很卡,交了10發1發過其它全90,看評測機溫度...

**:(其實不長都是卡常痕跡...)

#includeusing namespace std;

const int n=1e6+100;

const int inf=1e9;

const int bf=1e7;

char gc()

templatevoid rd(t &x)

templatevoid print(t x)

void mx(int &x,int y)

int n,m,a[n];

int son[n],siz[n];

int f[n],g[n];

vectormp[n];

struct mat

int ask()

void in(int x,int y)

};mat operator *(const mat &x,const mat &y)

void dfs0(int x,int fa)

}void dfs1(int x,int fa)}}

int bd(int top,int f)

}tnum=0;

for(int x=top;x;x=son[x])tax[++tnum]=x;

return bd_chain(1,tnum);

}void init()

void qry(int x,int y)

x=fa[x];

}print(las_ans=seg[rt].ask());

}void sol()

}int main()

dfs0(1,0),dfs1(1,0);

gbt::init(),gbt::sol();

}

全域性平衡二叉樹

考慮重鏈剖分的時候,我們實際上是對每條重鏈的這個區域性開乙個資料結構維護,而lct是對整顆樹去維護乙個大splay,考慮將lct的思想應用到輕重鏈剖分中。或者考慮lct維護動態dp的時候,每次進行樹的形態調整常數是不是過大了,那麼考慮運用靜態的鏈剖分,用乙個形態不變的平衡樹維護整顆樹。實際上,全域性...

平衡二叉樹例題 平衡二叉樹

acwing 72.平衡二叉樹 思路一 求每個節點的左右子樹深度,根據深度差判斷,直到葉子節點結束,效率不夠高,每個節點都要用兩次計算深度的遞迴函式 思路二 從葉子節點開始,計算深度差,一旦有深度差大於1的,就直接返回0,也不用管上面的深度是不是正確了,畢竟我們只需要true和false兩種狀態,省...

二叉樹 平衡二叉樹

1.題目 給定乙個二叉樹,判斷這棵二叉樹是否是高度平衡的二叉樹 平衡二叉樹 乙個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過1 2.題目分析 1 如果乙個節點的兩個子樹的深度之差超過1,則不是平衡二叉樹 2 如果乙個節點的兩個子樹的深度之差不超過1,則是平衡二叉樹 3.程式分析 1 若這棵二...