考慮重鏈剖分的時候,我們實際上是對每條重鏈的這個區域性開乙個資料結構維護,而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 若這棵二...