10 24T2 樹鏈剖分

2022-05-01 18:27:16 字數 3031 閱讀 5109

2.盟主的憂慮

(worry)

【問題描述】

江湖由 n 個門派(2≤n≤100,000,編號從 1 到 n)組成,這些門派之間有 n-1 條小道將他們連線起來,每條道路都以「尺」為單位去計量,武林盟主發現任何兩個門派都能夠直接或者間接通過小道連線。

雖然整個江湖是可以互相到達的,但是他擔心有心懷不軌之徒破壞這個武林的安定,破壞小道,於是武林盟主又秘密地修建了 m 條密道(1≤m≤100,000),但每條小道距離都不超過10億尺。

果不其然,最近乙個名叫「太吾」的組織意欲破壞武林的小道,請你幫盟主想想辦法,如果門派 a 到門派 b 的直連小道被破壞,從 a 走到 b 的所有路徑中,經過密道的距離最少是多少? 

【輸入】

第一行數字 n m

接下來 n-1 行,每行兩個整數 a b,表示 a-b 間有一條直連小道

接下來 m 行,每行三個數字 a b v,表示 a-b 間有一條代價為 v 的密道

【輸出】

輸出 n-1 行,對應原輸入的小道,每個小道被破壞後,最少需要經過多長的密道?如果不存在替換的道路,請輸出-1

【樣例輸入】

6 34 1

1 34 5

1 26 5

3 6 8

2 3 7

6 4 5

【樣例輸出】

【資料範圍與約定】

30%資料:n<=300,m<=1000

50%資料:n<=1000,m<=1000

70%資料:n<=5000,m<=5000

對於另外15%的資料點:樹是一條鏈

100%資料:n,m<=100,000

一條密道影響的是連線兩點之間的簡單路徑,所以我們就可以用樹鏈剖分覆蓋兩點之間的邊,維護一下最小值就可以了,查詢的時候所有邊打包在一起查詢就完成了

此題需要擴棧

code:

1 #include2 #include3 #include4 #include5

#define lc (p<<1)

6#define rc (p<<1|1)

7#define n 1000006

8using

namespace

std;

9const

long

long inf=99999999999;10

struct

nodee[n];

13struct

nodeq[n];

16bool cmp(const node&a,const node&b)

19long

long

first[n],nxt[n],cnt,ans[n];

20void add(long

long u,long

long v,long

long

w)27

struct

tt[n];

30void pushnow(long

long p,long

long

v)33

void pushdown(long

long

p)39}40

void build(long

long p,long

long l,long

long

r)47

void update(long

long p,long

long ql,long

long qr,long

long

v)52

pushdown(p);

53long

long mid=t[p].l+t[p].r>>1;54

if(ql<=mid)update(lc,ql,qr,v);

55if(qr>mid)update(rc,ql,qr,v);56}

57long

long

siz[n],hson[n],dep[n],top[n],num[n],pre[n],tot,fa[n];

58void count(long

long

p)63

pushdown(p);

64count(lc);

65count(rc);66}

67void dfs1(long

long x,long

long

father)77}

78void dfs2(long

long x,long

long tp,long

long

father)88}

89long

long modify(long

long x,long

long y,long

long

v)95

if(dep[x]96if(num[y]+1

<=num[x])update(1,num[y]+1

,num[x],v);97}

98int

main()

110 fa[1]=1

;111 dfs1(1,1

);112 dfs2(1,1,1

);113 build(1,1

,tot);

114for(long

long i=1;i<=m;i++)

117 sort(q+1,q+m+1

,cmp);

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

121 count(1

);122

for(long

long i=1;i<=cnt;i+=2

)127 exit(0

);128

return0;

129 }

over

11 03T2 樹鏈剖分

給你一棵樹,每次詢問樹上兩條鏈是否有交點。第一行n,表示n個結點 第二行開始n 1行倆個 數x y,表示x,y有一條邊 接下來q,表示q個詢問 接下來q行四個數a b c d,詢問a到b的鏈是否與c到d的鏈有交點 輸出q行 yes或no sample input 輸入1 1 21 3 2 42 5 ...

樹鏈剖分 樹鏈剖分講解

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

bzoj4034 T2 樹鏈剖分 樹狀陣列

一種明顯的做法是直接樹鏈剖分然後用區間修改區間查詢樹狀陣列 我寫的這種 或者線段樹來維護吧。這樣做是o nlog 2n 的。但是還可以做到o nlogn 首先可以發現它是單點鏈上查詢,那麼可以考慮用差分的思想,或者考慮將單點修改直接變成區間修改然後就只用單點簡單查詢了。首先考慮單點修改,這種操作只對...