十分weak的樹鏈剖分初步
給一棵樹,實現兩個功能:
①給兩個節點u,v,給u,v路上的每條邊權值加a
②給兩個節點u,v,求u,v路上所有邊的權值之和
1 #include2 #include3 #include4 #include5using
namespace
std;
67 inline int
read()
1617
struct
edge
21};
2223
const
int maxn=100001;24
25 vectoredges;
26 vectortree;
27int
head[maxn],tmp_head[maxn];
28int
n,q,root,cnt;
29int
fat[maxn],dep[maxn],siz[maxn],son[maxn],top[maxn],id[maxn];
30//
b[i]表示區間1...i變化量
31int b[101
];32
//c[i]表示區間1...i變化量的總和,有c[i]=b[i]*i
33int c[101
];34
35 inline void add_edge(int
from,int
to)41
42 inline void add_tree(int
from,int
to)46
47void
init()55}
5657
void dfs_1(int x,int
fa)70 siz[x]+=siz[edges[ee].to];71}
72}7374
void dfs_2(int
x)80
for(int ee=head[x];ee;ee=tree[ee].next)
81if(tree[ee].to!=son[x])86}
8788
void
make()
9899
void add_b(int x, int
c)100
103104
void add_c(int x, int
c)105
108109
int add(int left,int right,int
c)115
}116
117int sum_b(int
x)118
123124
int sum_c(int
x)125
130131
int sum(int
x)132
136137
int sum(int left,int
right)
140141
void cha(int u,int v,int
a)148
add(id[f1],id[u],a);
149 u=fat[f1]; f1=top[u];
150}
151if(u==v) return
;152
if(dep[u]153add(id[son[v]],id[u],a);
154}
155156
int calc(int u,int
v)164 len+=sum(id[f1],id[u]);
165 u=fat[f1]; f1=top[u];
166}
167if(u==v) return
len;
168if(dep[u]169 len+=sum(id[son[v]],id[u]);
170return
len;
171}
172173
void
solve()
180else
183}
184}
185186
intmain()
她會好嗎 還是更爛
對我而言 是另一天
樹鏈剖分 樹鏈剖分講解
好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 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 摘要 線段樹的基本 建樹 區間查詢 單點修改 及高階操作 區間修改 單點查詢 區間修改 區間查詢 標記下傳 標記永久化 閱讀全文 樹鏈剖分用...
樹鏈剖分 樹剖換根
這是一道模板題。給定一棵 n 個節點的樹,初始時該樹的根為 1 號節點,每個節點有乙個給定的權值。下面依次進行 m 個操作,操作分為如下五種型別 換根 將乙個指定的節點設定為樹的新根。修改路徑權值 給定兩個節點,將這兩個節點間路徑上的所有節點權值 含這兩個節點 增加乙個給定的值。修改子樹權值 給定乙...