參考
本博文又名:手把手教你寫樹狀數組
1. 單點修改,子樹和查詢
單點修改,區間查詢
樹狀數組
維護每個點的權值:
1. 修改add(x,w);
2. 查詢ans=query(le[x])-query(ri[x]-1);
2. 單點修改,樹鏈和查詢
首先將
考慮修改點
至於查詢,則是四個單點查詢。
線段樹
維護每個節點到
1. 修改modify(1,le[x],ri[x],w);
2. 查詢
ans=query(1,u)+query(1,v)-query(1,lca(u,v))-query(1,fa(lca(u,v)));
(本質上即四次查詢query(1, x);
)
樹狀數組
前綴和維護點到
1. 修改add(le[x],w),add(ri[x]+1,-w);
2. 查詢ans=[u,v]間權值和的初始值+query(le[u])+query(le[v])-query(le[lca(u,v)])-query(le[fa(lca(u,v))]);
(本質上即四次查詢query(x);
)
3. 樹鏈修改,單點查詢
樹鏈修改的道理同上,等價於修改某個點到
考慮修改的樹鏈的一個端點爲
對於點
樹狀數組
維護每個點權值的變化量:
1. 修改add(u,w),add(v,w),add(lca(u,v),-w),add(fa(lca(u,v)),-w);
(本質上即四次修改add(x,w);
)
2. 查詢ans=x的初始值+query(ri[x])-query(le[x]-1);
4. 樹鏈修改,子樹和查詢
樹鏈修改的道理同上,等價於修改某個點到
考慮修改的樹鏈的一個端點爲
仍是單點修改,區間查詢
樹狀數組
開兩個樹狀數組,分別維護
1. 修改
add1(u,w*(depth[u]+1)),add1(v,w*(depth[v]+1)),add1(lca(u,v),-w*(depth[lca(u,v)]+1)),add1(fa(lca(u,v)),-w*(depth[fa(lca(u,v)]+1);
add2(u,w),add2(v,w),add2(lca(u,v),-w),add2(fa(lca(u,v)),-w);
(本質上即八次修改add(x,w);
)
2. 查詢
ans=子樹和的初始值+query1(ri[x])-query1(le[x]-1)-depth[x]*(query2(ri[x])-query2(le[x]-1));
5. 子樹修改,單點查詢
區間修改,單點查詢
樹狀數組
前綴和維護點權值的變化量:
1. 修改add(le[x],w),add(ri[x]+1,-w);
2. 查詢ans=x的初始值+query(le[x]);
6. 子樹修改,子樹和查詢
區間修改,區間查詢
線段樹
維護每個點的權值
1. 修改add(1,le[x],ri[x],w);
2. 查詢ans=query(1,le[x],ri[x]);
樹狀數組
具體見【小結】樹狀數組的區間修改與區間查詢 ——MoeO3,本菜就不多廢話了_(:3」∠)_
(已經赤果果地變成一篇樹狀數組的文章啦(逃
7. 子樹修改,樹鏈和查詢
樹鏈修改的道理同2. 3. 4. ,等價於修改某個點到
考慮修改
樹狀數組
開兩個樹狀數組,分別維護
1. 修改
add1(le[x],w[x]*(-depth[x]+1);add1(ri[x]+1,-w[x]*(-depth[x]+1);
add2(le[x],w[x]);add2(ri[x]+1,-w[x]);
2. 查詢
ans=[u,v]間權值和的初始值+(query1(le[u])+query1(le[v])-query1(le[lca(u,v)])-query1(le[fa(lca(u,v))]))+depth[y]*(query2(le[u])+query2(le[v])-query2(le[lca(u,v)])-query2(le[fa(lca(u,v))]));
(本質上即八次查詢query(x)
)
完結撒花~
哪裏有錯誤還煩請批評指正啦