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