顯然qtree系列都是樹鏈剖分辣
發現自己沒有專門整理過樹鏈剖分耶
辣麼就把這篇部落格魔改成樹鏈剖分好辣(貌似除了樹剖也沒什麼好寫的)
廢話了辣麼多終於開始了
一.樹剖怎麼寫鴨
二.樹剖有什麼用鴨
三.qtree3題解
樹剖,顧名思義就是把樹 剖成一條一條的東西,然後把一棵樹搞成乙個序列。
咋剖?對於樹上的每個節點,我們定義它的兒子中,有著最大子樹的兒子就是重兒子(因為它畫出來顯得比較重),然後我們從根節點開始,一直走重兒子,就走出來一條重鏈。那些不在重鏈上的邊怎麼辦呢?我們給他們起個名字,叫輕邊。
處理重兒子
void dfs1(int u,int fa)
}
辣麼我們搞這個重鏈到底有什麼用呢
良(du)心(liu)出題人肯定會搞一些樹上的詢問對不對?樹上的詢問一般都要涉及兩個點之間的路徑對不對?要搞路徑就要找lca對不對?這時候就要用到重鏈和輕邊了。
對於每一條鏈都會有乙個鏈的頂部(一條輕邊自己就是一條鏈),我們可以一條鏈一條鏈的往上跳,也就是每次都跳到當前所在鏈的頂部再往上乙個點(以便找下乙個頂部)。這樣,當再跳一步,兩個點所在鏈的頂部相同時,就說明lca在這條鏈中。
再蒟個栗子
現在我們要求6和8的lca
圖中加粗的點是重兒子
6所處的鏈的頂端是1,8的頂端是10
這裡我們先跳頂端比較深的那個點,也就是跳8
如果跳這一步:
這時候發現2和6的頂端是一樣的,說明6和8的lca肯定在1->2->4->6這條鏈中
那麼2和6中靠近根的點就是lca,在這裡就是2。
查詢**(以求點權之和為例)
int sum(int x,int y)
什麼?線段樹怎麼寫?點這裡qwq至於線段樹維護什麼因題而異,這裡就不多說辣。
樹剖可以對樹進行操作,然後把樹搞成乙個區間,再加上線段樹等資料結構的輔助,從而讓我們的暴力跑的更快(港真樹鏈剖分其實是乙個優化暴力)
經典型別(可能以後會補充):原本序列上的操作被duliu出題人搞到了樹上;給出的圖是一棵樹而且還會神煩的改邊權
[傳送](
!(!(
乙個大小坑:
我們在樹剖的時候建的是雙向邊,所以注意#####陣列要開到2e5!!!!!
鑑於luogu是個神奇的**,不開2e5的邊的評測結果是這樣的:
emmmm當時真的以為是query無限遞迴什麼的然後愣是wa了乙個月沒調出來,某天吃飯的時候突然醒悟邊tm開小了
code:
#include#include#include#include#include#include#define pa pairtypedef long long ll;
using namespace std;
inline int read()
while(ch>='0'&&ch<='9')
return f?-x:x;
}const int inf=21474836;
int fir[300009],dfn[100009],son[100009],par[100009],top[100009];
int n,q,dep[100009],cnt,head[100009],sz[100009];
int tim,idx[100009];
struct eed[300009];
void add(int fr,int to)
void dfs1(int now,int fa)
return ;
}void dfs2(int now,int fa)
// printf("dfn[%d]=%d\n",now,dfn[now]);
}void build(int k,int l,int r)
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
fir[k]=inf;
}void chg(int k,int l,int r,const int &v)
int mid=(l+r)>>1;
if(v<=mid) chg(k<<1,l,mid,v);
else chg(k<<1|1,mid+1,r,v);
fir[k]=min(fir[k<<1],fir[k<<1|1]);
}int query(int k,int l,int r,const int &x,const int &y)
int mid=(l+r)>>1;
int rtn=inf;
if(x<=mid) rtn=min(rtn,query(k<<1,l,mid,x,y));
if(middep[y])swap(x,y);
rtn=min(rtn,query(1,1,n,dfn[x],dfn[y]));
return rtn;
}int main()
{ n=read();q=read();
for(int i=1;i好了在結尾安利一道樹剖模板題
LCA的樹鏈剖分實現
這篇本來是要在 樹鏈剖分小節 中寫的,但是我感覺這只是樹鏈剖分的乙個衍生物,所以另開了一篇,如果對樹鏈剖分部分還不是太了解,請看上面的鏈結。計算樹中兩個節點的最近公共祖先,我們一般有爬山法,tarjan離線演算法,或者是將lca轉換成rmq來解,這裡講一講一種新的求lca的演算法,它是基於樹鏈剖分的...
狐假虎威的樹鏈剖分
運算元據結構 線段樹 結束語 最近在做運輸計畫這道題時,發現要用數鏈剖分,於是就打算學學這個玩意兒。其實之前一直以為這個東西是個很複雜的東西,可能 看起來都很長。但是,學了之後,我才發現,這個東西很好懂,而且 之所以很長,也有乙個原因就是它需要使用乙個強大的資料結構 線段樹。線段樹的 其實並不算少,...
樹鏈剖分的學習理解
前言 本文僅為本人學習樹鏈剖分的理解和總結,有誤之處請大佬指點迷津。也有與其他部落格不同或矛盾之處。樹鏈剖分 顧名思義,將樹結構,剖分成鏈狀結構,然後將一條條的鏈拼接成線性結構,然後就可以通過線段樹 樹狀陣列等維護了。說白了就是在樹上,有些值不好維護,通過樹鏈剖分轉化成乙個序列,而序列就好維護了。樹...