洛谷P3384 樹鏈剖分

2022-08-03 02:54:09 字數 2446 閱讀 3136

這是一道樹鏈剖分的模板題,首先要學會線段樹、dfs、鏈式前向星之類的,不然……//打暴力吧

本題很考驗**能力,難度不大,主要是細節繁多。(我調了1h)

樹鏈剖分的原理不再贅述(詳見《資訊學奧賽一本通·提高版》),主要說一下一些容易錯的細節。

1 #include 2 #include 3 #include 4 typedef long

long

ll;5 inline int

read()

9while(c<='

9'&&c>='

0') ret=ret*10+c-'

0',c=getchar();

10return ret*f;11}

12using

namespace

std;

13const

int n=100010;14

intn,m,root,mod;

15int

val[n],fa[n],top[n],size[n],son[n],d[n];

16int seg[n],rev[n],sum[n<<2],tag[n<<2

];17

intans;

18struct

edge a[n<<1

];21

int num,head[n<<1

];22 inline void add(int

from,int

to)

27void dfs1(int u,int

f) 38}39

void dfs2(int u,int

f) 46

for(int i=head[u];i;i=a[i].next) 54}

55}56 inline void pushdown(int now,int

len) 66}

67 inline void build(int now,int l,int

r) 73

int mid=l+r>>1

;74 build(now<<1

,l,mid);

75 build(now<<1|1,mid+1

,r);

76 sum[now]=sum[now<<1]+sum[now<<1|1

];77 sum[now]%=mod;78}

79void updata(int now,int l,int r,int x,int y,int

z) 86 pushdown(now,r-l+1

);87

int mid=l+r>>1;88

if(x<=mid) updata(now<<1

,l,mid,x,y,z);

89if(y>mid) updata(now<<1|1,mid+1

,r,x,y,z);

90 sum[now]=sum[now<<1]+sum[now<<1|1

];91 sum[now]%=mod;92}

93void query(int now,int l,int r,int x,int

y) 99 pushdown(now,r-l+1

);100

int mid=l+r>>1

;101

if(x<=mid) query(now<<1

,l,mid,x,y);

102if(y>mid) query(now<<1|1,mid+1

,r,x,y);

103}

104void find(int x,int y,int z,int

op)

112if(d[x]>d[y]) swap(x,y);

113if(op==1) updata(1,1,seg[0

],seg[x],seg[y],z);

114else query(1,1,seg[0

],seg[x],seg[y]);

115 ans%=mod;

116}

117void find(int x,int y,int

op)

122int

main()

139else

if(op==2

) 146

else

if(op==3

) 150

else

157}

158return0;

159 }

ac code

**較長,盡量讓**簡潔,明亮,避免除錯時出現噁心現象(生理上的不適)

注意對答案的取模

線段樹的細節注意(標記下傳)

注意區分seg和rev的含義,避免混淆

dfs2函式的寫法(第48行)

千萬不能讓讀入優化、建圖、dfs這些基本的函式出錯,在寫的時候慢一點,避免手殘。否則欲哭無淚(難以置信自己居然錯在這裡)……555

洛谷 P3384 模板 樹鏈剖分

如題,已知一棵包含n個結點的樹 連通且無環 每個節點上包含乙個數值,需要支援以下操作 操作1 格式 1 x y z 表示將樹從x到y結點最短路徑上所有節點的值都加上z 操作2 格式 2 x y 表示求樹從x到y結點最短路徑上所有節點的值之和 操作3 格式 3 x z 表示將以x為根節點的子樹內所有節...

P3384 模板 樹鏈剖分 洛谷

題目鏈結 如題,已知一棵包含n個結點的樹 連通且無環 每個節點上包含乙個數值,需要支援以下操作 操作1 格式 1 x y z 表示將樹從x到y結點最短路徑上所有節點的值都加上z 操作2 格式 2 x y 表示求樹從x到y結點最短路徑上所有節點的值之和 操作3 格式 3 x z 表示將以x為根節點的子...

洛谷 P3384 模板 樹鏈剖分

樹鏈剖分詳情 跳轉大佬部落格 解題心得 個人看來其實樹鏈剖分就是把一棵標號沒有實際意義的樹重新標號,標號的規則按照重鏈優先,在有序之後用線段樹之類的資料結構來維護。include using namespace std const int maxn 1e5 100 struct node node ...