樹鏈剖分是一種應付樹上修改和查詢的演算法(資料結構),要求樹的形態不發生改變(改變的要用lct維護)
樹剖可以解決如下問題:路徑修改(查詢),子樹修改(查詢),單點修改。
其實有的題目dfs序即可,還有的要用點分治會明顯方便一些。
本模板支援:輸入p,q,查詢p,q的路徑上的權值和,給定p,w,將p子樹權值增加w,單點增加權值(其實怎麼搞都好,只要樹的形態不改變,修改滿足線段樹要求)
1 #include2view code#define maxn 1000
3struct node;
4 node seg[6*maxn];
5int
tot,n,op,fr[maxn],to[maxn],nxt[maxn],w[maxn];
6int
deep[maxn],fa[maxn],id[maxn],son[maxn],ori[maxn],top[maxn],end[maxn];
7void adde(int p,int q)
8void swp(int &p,int &q)
9int dfs1(int,int
);10
void dfs2(int,int
);11
void push(int
);12
int build(int
);13
void upd(int,int,int,int
);14
int que(int,int,int
);15
int ask(int,int
);16
intmain()
1722
for(i=1;i<=n;i++) scanf("
%d",&w[i]);
23 tot = 0; top[1] = 1; id[1] = ++tot; ori[1] = w[1
];24 dfs1(1,0); dfs2(1,0
);25
for(i=1;i<=n;i++) printf("
%d ",id[i]); printf("\n"
); 26
for(i=1;i<=n;i++) printf("
%d ",end[i]); printf("\n"
);27 seg[1].l = 1; seg[1].r =n;
28 build(1
);29
//for(i=1;i<30;i++) printf("i %d l %d r %d sum %d\n",i,seg[i].l,seg[i].r,seg[i].sum);
30char flag[20
];31
for(i=1;i<=op;i++)
3235
else
if(flag[0]=='c')
36else 37}
38return0;
39}40int dfs1(int now,int
f)41
50 sum +=siz;51}
52return sum+1;53
}54void dfs2(int now,int
f)55
58int
i,t;
59for(i=fr[now];i;i=nxt[i])
6066 end[now] =tot; 67}
68void push(int
now)69
76} 77}
78int build(int
now)
7982
int mid = (t.l+t.r)>>1; int lc = now<<1; int rc = lc|1
;83 seg[lc].l = t.l; seg[lc].r =mid;
84 seg[rc].l = mid+1; seg[rc].r =t.r;
85 seg[now].sum = build(lc)+build(rc);
86return
seg[now].sum;87}
88void upd(int now,int l,int r,int
w)89
97int lc = now<<1; int rc = lc|1;98
upd(lc,l,r,w); upd(rc,l,r,w);
99 seg[now].sum = seg[lc].sum +seg[rc].sum;
100}
101int que(int now,int l,int
r)102
108int ask(int p,int
q)109
115 ret += que(1
,id[fa1],id[p]);
116 p = fa[fa1];fa1 =top[p];
117}
118if(deep[p]
119return ret+que(1
,id[q],id[p]);
120 }
樹鏈剖分 模板
class match node a n struct no no aa n 4 void init void addpage int x,int y void dfs int s,int faa,int h 根節點,父節點和深度的 if max 0 son s sign void dfs2 int...
模板 樹鏈剖分
define maxn 50010 define l u u 1 define r u u 1 1 寫在類裡面爆棧 int n,m,q int tim 時間戳 int num maxn 樹上每個節點的初始值 int siz maxn siz u 表示以u為根的子樹的節點數 int top maxn ...
樹鏈剖分模板
點權模板 1 m a b c將節點a到節點b路徑上所有點都染成顏色c 2 q a b詢問節點a到節點b路徑上的顏色段數量 連續相同顏色被認為是同一段 如 112221 由3段組成 11 222 和 1 const int n 100100 struct edge g n 2 int cnt,head...