樹鏈剖分是解決在樹上進行插點問線,插線問點等一系列樹上的問題
假如現在給你一棵樹,然後沒兩條邊之間有一條權值,有一些操作,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 摘要 線段樹的基本 建樹 區間查詢 單點修改 及高階操作 區間修改 單點查詢 區間修改 區間查詢 標記下傳 標記永久化 閱讀全文 樹鏈剖分用...