樹鏈剖分學習小記

2021-07-09 20:21:15 字數 1969 閱讀 6032

入門題:【zjoi2008】樹的統計

description

一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。

我們將以下面的形式來要求你對這棵樹完成一些操作:

i. change u t : 把結點u的權值改為t

ii. qmax u v: 詢問從點u到點v的路徑上的節點的最大權值

iii. qsum u v: 詢問從點u到點v的路徑上的節點的權值和

注意:從點u到點v的路徑上的節點包括u和v本身

solution

很裸的樹鏈剖分
code

#include

#include

#include

#include

#include

#define fo(i,a,b) for(i=a;i<=b;i++)

using namespace std;

const int maxn=100000;

int i,j,k,l,t,n,m,ans,size[maxn],deep[maxn],top[maxn],fa[maxn],son[maxn],w[maxn];

int first[maxn],last[maxn],next[maxn],num,a[maxn],tot,q,p,fw[maxn];

char s[10];

struct nodetree[maxn*5];

void add(int

x,int

y)void dfs1(int

x,int

y) }

}}void dfs2(int

x,int

y) }

}void build(int

x,int l,int r)

else

}void change(int

x,int l,int r,int

y,int z)

else

}int query_max(int

x,int l,int r,int

y,int z)

else

}}int query_sum(int

x,int l,int r,int

y,int z)

else

}}int find_max(int

x,int

y) o=max(o,query_max(1,1,n,w[f1],w[x]));

x=fa[f1];f1=top[x];

}if(deep[x]>deep[y]) swap(x,y);

return max(o,query_max(1,1,n,w[x],w[y]));

}int find_sum(int

x,int

y) o+=query_sum(1,1,n,w[f1],w[x]);

x=fa[f1];f1=top[x];

}if(deep[x]>deep[y]) swap(x,y);

return o+query_sum(1,1,n,w[x],w[y]);

}int main()

fo(i,1,n) scanf("%d",&a[i]);

deep[1]=1;

dfs1(1,0);

dfs2(1,1);

build(1,1,n);

scanf("%d",&q);

fo(p,1,q)

else

if(s[2]=='m')

else

if(s[2]=='s')

}}

樹鏈剖分 模板小記

樹鏈剖分 模板小記 q.樹鏈剖分的背景?a.連通且無環的樹 q.樹鏈剖分的作用?a.大幅增加碼量 a.將一棵樹變成幾條鏈 樹形變成線形 減少處理難度 q.樹鏈剖分能處理哪些問題?a 1.修改的有 將 x 節點 or times val 將 x 到 y 這條路徑上所有節點 or times val 將...

樹鏈剖分學習

樹鏈剖分 看了學習了樹鏈剖分 適用於在樹上的路徑操作。關鍵在於重鏈的構造,把它表示到了資料結構上的連續區間,降低了複雜度。主要操作步驟實際上有三個部分 1 構造重鏈 2 如何維護資料 3 分解為輕重鏈的查詢與修改 include include include include define n 10...

樹鏈剖分學習

之前寫過樹剖的題,但沒有完全理解,現在又無法複述思路了,所以重新學習一下,部分語句參考大神的敘述 一 概念 樹鏈剖分,顧名思義,樹是由一根根樹鏈組成的,我們現在要來把它按鏈來分解掉。我們知道,大部分樹上的問題都是圍繞樹的路徑來做文章,分解成一條條的鏈之後,我們就可以對節點 邊 就行編號了,而同一根鏈...