POJ 3417 樹上差分

2021-09-28 19:32:48 字數 1564 閱讀 8373

基本操作

來自1.已知路徑求被所有路徑覆蓋的邊

首先對已知的這 n 條路徑的 起點a 和 終點b 的權值 +1,並對 lca(a, b) 的權值 -2 。

從根節點開始深搜,回溯時將其本身的權值加上所有子節點的權值。

那麼滿足要求的邊就是 權值等於n的節點與其父節點所連的邊

void

dfs(

int x,

int father)

}}

2.已知路徑求樹上所有節點被路徑覆蓋次數

對每條路徑的 起點a和終點b 的權值 +1 , 對 lca(a, b) 的權值 -1,對 lca(a, b)的父節點 權值 -1

從根節點開始深搜,回溯時將其本身的權值加上所有子節點的權值

每個節點的權值既是其被路徑覆蓋的次數

原來的圖是一棵樹,新增的m條邊

每增加一條,一定會構成乙個u-lca(u,v)-v-u的乙個環

每兩個節點之間的邊一定都會被一些環給覆蓋 稱為覆蓋數

計算原圖中每條邊的覆蓋數

如果覆蓋數為0 那麼這條邊只要被刪除,新圖中任意刪去一條邊 整個network都會被分割

如果覆蓋數為1 那麼刪除這條邊和新圖中對應的邊 也會被分割

只有覆蓋數為2 這兩個點才不會被分割

**:

#include

#define ll long long

#define db double

#define n 1000005

using

namespace std;

intread()

while

(ch>=

'0'&&ch<=

'9')

return f*x;

}int first[n]

,net[n]

,to[n]

,dep[n]

,f[n][25

],cnt[n]

;int n,m,s,x,y,tot;

bool vis[n]

;void

add(

int x,

int y)

void

deal

(int e,

int fa)

}int

lca(

int x,

int y)

for(

int i=

19;i>=

0;i--

)return f[x][0

];}void

get(

int u)}}

intmain()

deal(1

,0);

for(

int i=

1;i<=m;i++

)get(1

);int ans=0;

for(

int i=

2;i<=n;i++

)printf

("%d"

,ans)

;return0;

return0;

}

樹上差分的整理(點的樹上差分和邊的樹上差分)

點的樹上差分 若經過 u 到 v 的所有點,tmp u tmp v tmp lca u,v tmp parent lca u,v 0 例題 include using namespace std struct ss ss data 600010 int n,q int a 300010 head 6...

差分 樹上差分略解

差分 樹上差分略解 哈哈差分?先來看一道題 題目描述 給定包含 n個數的陣列 a1,a2,an.有 k次操作 每次操作把區間 l,r 加上v 最後求出數列每個位置的數。輸入格式 第一行,n.第二行,a1,a2,an下一行,k,下k行,每行乙個操作,格式為l,r,v 輸出格式 一行,更新後的陣列 樣例...

差分總結二 樹上差分

找這個樹上 重複經過的最多點 經過幾次 看這名字 就醉了orz 這題是 樹上差分 模板題 點差分 點差分的話 由於 lca 本身是有貢獻的 那麼d lca 用d lca父親 只要消掉影響 include using namespace std const int maxn 1e5 10 int n,...