模板 樹鏈剖分

2022-09-04 01:12:14 字數 2550 閱讀 5157

樹鏈剖分是一種應付樹上修改和查詢的演算法(資料結構),要求樹的形態不發生改變(改變的要用lct維護)

樹剖可以解決如下問題:路徑修改(查詢),子樹修改(查詢),單點修改。

其實有的題目dfs序即可,還有的要用點分治會明顯方便一些。

本模板支援:輸入p,q,查詢p,q的路徑上的權值和,給定p,w,將p子樹權值增加w,單點增加權值(其實怎麼搞都好,只要樹的形態不改變,修改滿足線段樹要求)

1 #include2

#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 }

view code

樹鏈剖分 模板

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...