感覺是樹剖和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 若這棵二...