數鏈剖分(Aragorn s Story )

2022-03-05 17:19:31 字數 2836 閱讀 8948

題目大意:n個點,m條邊,然後q次詢問,因為在樹上,兩個點能確定一條直線,我們可以對這條直線上的所有值進行加減操作,也可以單點詢問。

各個陣列的作用:sto是剛開始的輸入資料,head是前向星,dfsnum指的是dfs序,depth指的是每個點的深度son指的是每個節點的重兒子,father指的是每個點的父節點,size指的是以當前點為根節點的樹,ord指的是遍歷順序,cost指的是編號之後的每個點,top指的是當前的這條重鏈的最頂端的那個點,剩下的就是線段樹的陣列了。

注意點:我們通過兩個dfs來給這些陣列賦值,通過第乙個dfs,我們可以把depth和father,size,son求出來,剩下的ord和top通過第二個dfs求出來,為什麼使用兩個dfs?我的理解就是,第乙個dfs和第二個dfs的遍歷條件並不相同,第乙個dfs就是能走就走,第二個dfs是在按照已經分好鏈的前提下進行走的,也就是說這裡的ord陣列並不能在第乙個dfs中實現,只能在第二個陣列中實現。(後續有新的理解會繼續補充)。

ac**:

1 #include2 #include3 #include4 #include5 #include6 #include

7 #include8 #include9

using

namespace

std;

10 # define inf 0x3f3f3f3f

11 # define ll long

long

12 # define lson l,m,rt<<1

13 # define rson m+1,r,rt<<1|1

14const

int maxn = 5e4+100;15

intsto[maxn],head[maxn],edgnum,dfsnum,depth[maxn];

16int

son[maxn],father[maxn],size[maxn],ord[maxn],cost[maxn],top[maxn];

17int tree[maxn<<2],lazy[maxn<<2

];18

struct

node

19 edge[maxn<<2

];23

void addedge(int fr,int

to)24

29void dfs1(int fr,int rt,int

dep)

3046}47

}48void dfs2(int fr,int

rt)4962}

63}64void

init()

6570

void up(int

rt)71

74void down(int len,int

rt)7584}

85void buildtree(int l,int r,int

rt)86

94int m=(l+r)>>1;95

buildtree(lson);

96buildtree(rson);

97up(rt);98}

99void update(int l,int r,int rt,int l,int r,int

p)100

107 down(r-l+1

,rt);

108int m=(l+r)>>1

;109

if(l<=m)

110update(lson,l,r,p);

111if(r>m)

112update(rson,l,r,p);

113up(rt);

114}

115void update(int n,int x,int y,int

p)116

125 update(1,n,1

,ord[tx],ord[x],p);

126 x=father[tx],tx=top[x];

127}

128if(depth[x]129132 update(1,n,1

,ord[y],ord[x],p);

133}

134int query(int l,int r,int rt,int

pos)

135140 down(r-l+1

,rt);

141int ans=0

;142

int m=(l+r)>>1

;143

if(pos<=m)

144 ans+=query(lson,pos);

145if(pos>m)

146 ans+=query(rson,pos);

147return

ans;

148up(rt);

149}

150int

main()

151161

intt1,t2;

162for(int i=1; i<=m; i++)

163168

init();

169char str[10

];170 buildtree(1,n,1

);171

intt3;

172while(q--)

173180

else

if(str[0]=='q'

)181

186else

if(str[0]=='d'

)187

191}

192}

193return0;

194 }

數鏈剖分(Housewife Wind )

題目大意 給你n,q,s。n指的是有n個點,q代表有q次詢問,s代表的是起點。然後接下來會有n 1條邊,雙向邊,帶有權值,對於q次詢問,如果輸入的第乙個數是1,然後接下來會輸入兩個數,t1,t2。t帶邊將第t1條邊的權值改成t2.如果第乙個數是0,接下來會輸入乙個t,詢問從s到t的花費。具體思路 對...

數鏈剖分基礎講解

在一棵樹上進行路徑的修改 求極值 求和 乍一看只要線段樹就能輕鬆解決,實際上,僅憑線段樹是不能搞定它的。我們需要用到一種貌似高階的複雜演算法 樹鏈剖分。樹鏈,就是樹上的路徑。剖分,就是把路徑分類為重鏈和輕鏈。重兒子 siz u 為v的子節點中siz值最大的,那麼u就是v的重兒子。輕兒子 v的其它子節...

樹鏈剖分 樹鏈剖分講解

好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 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...