數鏈剖分(Housewife Wind )

2022-03-05 16:53:05 字數 2391 閱讀 9164

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

具體思路:對於邊權,我們可以改成點權,這條邊的權值賦給這條邊上深度大的那條邊,然後就是單點更新和區間查詢了。

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 = 1e5+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

];18

struct

node

19 edge[maxn<<2],po[maxn<<2

];25

void addedge(int fr,int

to)26

32void dfs1(int fr,int rt,int

dep)

3349}50

}51void dfs2(int fr,int

rt)5265}

66}67void up(int

rt)68

71void buildtree(int l,int r,int

rt)72

78int m=(l+r)>>1;79

buildtree(lson);

80buildtree(rson);

81up(rt);82}

83int query(int l,int r,int rt,int l,int

r)84

89int ans=0;90

int m=(l+r)>>1;91

if(l<=m)

92 ans+=query(lson,l,r);

93if(r>m)

94 ans+=query(rson,l,r);

95up(rt);

96return

ans;97}

98void update(int l,int r,int rt,int pos,int

p)99

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

;106

if(pos<=m)

107update(lson,pos,p);

108if(pos>m)

109update(rson,pos,p);

110up(rt);

111}

112int query(int n,int x,int

y)113

123 ans+=query(1,n,1

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

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

125}

126if(depth[x]127130

return ans+query(1,n,1,ord[y]+1

,ord[x]);//這個地方注意應該是ord[y]+1,如果我們詢問的是從3->5的,有可能3這個點是另一條邊的權值,所以應該把點往下移動乙個。

131}

132int

main()

133147 dfs1(1,-1,1

);148 dfs2(1,1

);149

for(int i=1; i<=n-1; i++)

150157 update(1,n,1

,ord[po[i].to],po[i].cost);

158}

159while(q--)

160170

else

171175

}176

return0;

177 }

數鏈剖分(Aragorn s Story )

題目大意 n個點,m條邊,然後q次詢問,因為在樹上,兩個點能確定一條直線,我們可以對這條直線上的所有值進行加減操作,也可以單點詢問。各個陣列的作用 sto是剛開始的輸入資料,head是前向星,dfsnum指的是dfs序,depth指的是每個點的深度son指的是每個節點的重兒子,father指的是每個...

數鏈剖分基礎講解

在一棵樹上進行路徑的修改 求極值 求和 乍一看只要線段樹就能輕鬆解決,實際上,僅憑線段樹是不能搞定它的。我們需要用到一種貌似高階的複雜演算法 樹鏈剖分。樹鏈,就是樹上的路徑。剖分,就是把路徑分類為重鏈和輕鏈。重兒子 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...