全域性平衡二叉樹

2022-04-29 20:42:11 字數 1600 閱讀 2772

考慮重鏈剖分的時候,我們實際上是對每條重鏈的這個區域性開乙個資料結構維護,而lct是對整顆樹去維護乙個大splay,考慮將lct的思想應用到輕重鏈剖分中。

或者考慮lct維護動態dp的時候,每次進行樹的形態調整常數是不是過大了,那麼考慮運用靜態的鏈剖分,用乙個形態不變的平衡樹維護整顆樹。

實際上,全域性平衡二叉樹是一顆二叉樹森林,其中的每顆二叉樹維護一條重鏈。但是這個森林裡的二叉樹又互有聯絡,其中每個二叉樹的根連向這個重鏈鏈頭的父親,就像lct中一樣。

我們的目的是使這個大二叉樹森林樹高\(\log\)。

於是我們對一條重鏈構建二叉樹的時候,實際上可以理解成每個點點權是帶權的,點權為輕子樹的點數和+1,然後每次我們取這個鏈的帶權中點作為根,遞迴處理子樹。

這就是全域性平衡二叉樹的構造方法。

在做動態dp修改的時候,如果是二叉樹中的父親是另一條重鏈中的點,就先把自己的舊貢獻去掉,再把新貢獻加上,最後updata父親,否則直接updata父親就好

洛谷p4751 【模板】動態 dp(加強版)

code:

#include #include #include using std::max;

const int size=(1<<21)+1;

char ibuf[size],*is=ibuf,*it=ibuf;

#define gc() (is==it?(it=(is=ibuf)+fread(ibuf,1,size,stdin),(is==it?eof:*is++)):*is++)

template void read(t &x)

const int n=1e6+10;

int n,m,val[n];

int head[n],to[n<<1],next[n<<1],cnt;

void add(int u,int v)

struct matrix

matrix(int a,int b,int c,int d)

matrix friend operator *(matrix a,matrix b)

}dat[n],mx[n];

int ch[n][2],par[n],root;

#define ls ch[now][0]

#define rs ch[now][1]

#define fa par[now]

void updata(int now)

int siz[n],lsiz[n],dp[n][2],ws[n];

void dfs(int now,int f)

int dfs1(int now,int f)

else

for(int v,i=head[now];i;i=next[i])

if((v=to[i])!=f&&v!=ws[now])

par[dfs1(v,now)]=now;

return rt;

}bool isroot(int now)

void upt(int now)

upt(fa);

}int main()

return 0;

}

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

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

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

感覺是樹剖和lct的一種結合,把樹剖的log 2變成log,把lct的常數變小,但是能維護的東西也有侷限性.實際上就是有時候維護的東西不需要lct的link cut操作,所以可以將樹建成一棵棵二叉平衡樹連在一起而不需要splay。具體建法就是先輕重鏈剖分,對每條重鏈建一棵bst,然後這棵bst的根通...

二叉樹 平衡二叉樹

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