樹鏈剖分(模版)

2021-06-26 12:49:44 字數 2102 閱讀 9611

樹鏈剖分是解決在樹上進行插點問線,插線問點等一系列樹上的問題

假如現在給你一棵樹,然後沒兩條邊之間有一條權值,有一些操作,1:x---y之間的最大權值是多少,2:改變x---y之間的權值

應用範圍:在一棵樹上進行路徑的修改、求極值、求和,這樣的樹,從底向上看每個點都只和乙個點相連,即任何兩點間都有唯一的路徑。

劃分重鏈輕鏈

資料結構:

這裡的線段樹中的位置,考慮方式是線的個數是點數-1,所以可以一一對應。使用p陣列

那麼就要想想辦法了,我們能不能把x--y之間的一些邊一塊兒查詢,這就是關於樹鏈剖分的重邊和輕邊,

重邊:某個節點x到孩子節點形成的子樹中節點數最多的點child之間的邊,由定義發現除了葉子節點其他節點只有一條重邊

重邊是可以放在一塊兒更新的,而有

性質:從根到某一點的路徑上輕邊、重邊的個數都不大於logn。

所以這樣查詢的時間複雜度相當於log2(n)

其實樹鏈剖分就是把邊雜湊到線段樹上的資料結構。

實現的話很簡單,用兩個dfs處理數數的資訊,重邊以及輕邊,然後就是一些線段樹的操作了。

模板「:以spoj 375 為例

#include #include #include #include using namespace std;

#define del(a,b) memset(a,b,sizeof(a))

const int n = 10005;

int dep[n],siz[n],fa[n],id[n],son[n],val[n],top[n]; //top 最近的重鏈父節點

int num;

vectorv[n];

struct tree

};tree e[n];

void dfs1(int u, int f, int d)

}void dfs2(int u, int tp)

}#define lson(x) ((x<<1))

#define rson(x) ((x<<1)+1)

struct tree

;tree tree[4*n];

void pushup(int x)

void build(int l,int r,int v)

int mid=(l+r)>>1;

build(l,mid,v*2);

build(mid+1,r,v*2+1);

pushup(v);

}void update(int o,int v,int val) //log(n)

int mid = (tree[o].l+tree[o].r)/2;

if(v<=mid)

update(o*2,v,val);

else

update(o*2+1,v,val);

pushup(o);

}int query(int x,int l, int r)

int mid = (tree[x].l + tree[x].r) / 2;

int ans = 0;

if (l <= mid) ans = max(ans, query(lson(x),l,r));

if (r > mid) ans = max(ans, query(rson(x),l,r));

return ans;

}int yougth(int u, int v)

ans = max(query(1,id[tp1], id[u]), ans);

u = fa[tp1];

tp1 = top[u];

}if (u == v) return ans;

if (dep[u] > dep[v]) swap(u, v);

ans = max(query(1,id[son[u]], id[v]), ans);

return ans;

}void clear(int n)

int main()

{ //freopen("input.txt","r",stdin);

int t;

scanf("%d",&t);

while(t--)

{int n;

scanf("%d",&n);

for(int i=1;i

樹鏈剖分模版

題目 spoj375 樹鏈剖分訓練題目 題意 給定一棵n節點的樹,有兩種操作,修改某一條邊的權值 查詢某一條鏈u v的權值最大的邊。分析 樹鏈剖分入門學習 對樹鏈剖分的初步認識 把樹上的邊分為兩類 重邊和輕邊。任意兩個節點u和v連線的這條鏈上,重鏈和輕邊的數目都不超過logn n為總的邊數 很明顯,...

樹鏈剖分 樹鏈剖分講解

好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 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...

演算法入門 樹鏈剖分 輕重鏈剖分

目錄 3.0 求 lca 4.0 利用資料結構維護資訊 5.0 例題 參考資料 資料結構入門 線段樹 發表於 2019 11 28 20 39 dfkuaid 摘要 線段樹的基本 建樹 區間查詢 單點修改 及高階操作 區間修改 單點查詢 區間修改 區間查詢 標記下傳 標記永久化 閱讀全文 樹鏈剖分用...