專題 樹鏈剖分

2021-08-07 14:23:06 字數 1947 閱讀 6846

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

#define ll long long int

const

int maxn=20000;

int t;

int n;

int dep[maxn];//儲存節點的深度

int son[maxn];//儲存節點的重兒子

int fa[maxn];//節點的父親

int sz[maxn];//以某個節點為根的子樹中節點的個數

int top[maxn];//top[v]表示節點v所在重鏈上最高的節點的編號

int indx;//用於求dfs序(嚴格來說不叫dfs序,先訪問重兒子的dfs序)時的標號

int maxn[maxn<<2];//線段樹

struct edge

; edge(int u,int v,int w,int next): u(u),v(v),w(w),next(next){}

}edge[maxn*2];

int edgecount;

int head[maxn];

void init()

inline

void add_edge(int u,int v,int w)

void dfs1(int u)//初始化dep son fa sz陣列

}void dfs2(int u,int ance)//初始化top tid陣列 ance表示重鏈的頂端節點

}///線段樹部分

inline

void pushup(int rt)

void update(int pos,int x,int l,int r,int rt)//將pos改為x

int m=(l+r)/2;

if(m>=pos)update(pos,x,l,m,rt*2);

else update(pos,x,m+1,r,rt*2+1);

pushup(rt);

}int query(int l,int r,int l,int r,int rt)//查詢區間[l,r]的最大值

int solve(int u,int v)//查詢兩個節點u v的最短路徑上的最大權值的邊

//調整成ance_u在上面

maxm=max(maxm,query(tid[ance_v],tid[v],1,indx,1));

v=fa[ance_v];

ance_v=top[v];

}if(u==v)return maxm;

if(dep[v] < dep[u])return max(maxm,query(tid[son[v]],tid[u],1,indx,1));//v在上面

else

return max(maxm,query(tid[son[u]],tid[v],1,indx,1));//u在上面

}int main()

dfs1(1);//1作為根節點開始遍歷,初始化dep,son,fa,size陣列

dfs2(1,1);

for(int i=1;iint u=edge[i].u , v=edge[i].v , w=edge[i].w;

if(dep[v] < dep[u])swap(edge[i].u,edge[i].v);//這個地方比較巧妙

update(tid[edge[i].v],w,1,indx,1);

}while(scanf("%s",op))

else

//change修改操作}}

return

0;}

專題 樹鏈剖分

樹鏈剖分 定義 size u 表示以節點u為根的子樹的節點個數 我們將乙個節點到它的兒子中size值最大的那個節點的邊定義為重邊,其他邊定義為輕邊 我們稱某條路徑為重路徑 或重鏈 當且僅當它全部由重邊組成 性質 我們可以證明對於每個點到根的路徑上都不超過o logn 條輕邊和o logn 條重路徑組...

樹鏈剖分 樹鏈剖分講解

好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 vector v maxn int size maxn dep maxn val maxn id maxn hson maxn top maxn fa maxn 定義 int edge 1,num 1 struct tree e ma...

樹鏈剖分 專題,學習記錄

理解了上面的那個部落格中的想法之後,你可以看這個神犇寫的 spoj上的 第一版 調了一下午 半晚上,第一次a的時候那真是excited include include include include include include using namespace std typedef long l...