BZOJ3307 雨天的尾巴

2022-02-06 00:44:27 字數 3115 閱讀 6225

n個點,形成乙個樹狀結構。有m次發放,每次選擇兩個點x,y

對於x到y的路徑上(含x,y)每個點發一袋z型別的物品。完成

所有發放後,每個點存放最多的是哪種物品。

第一行數字n,m

接下來n-1行,每行兩個數字a,b,表示a與b間有一條邊

再接下來m行,每行三個數字x,y,z.如題

輸出有n行

每i行的數字表示第i個點存放最多的物品是哪一種,如果有

多種物品的數量一樣,輸出編號最小的。如果某個點沒有物品

則輸出0

20 50

8 610 6

18 6

20 10

7 20

2 18

19 8

1 614 20

16 10

13 19

3 14

17 18

11 19

4 11

15 14

5 18

9 10

12 15

11 14 87

12 1 87

14 3 84

17 2 36

6 5 93

17 6 87

10 14 93

5 16 78

6 15 93

15 5 16

11 8 50

17 19 50

5 4 87

15 20 78

1 17 50

20 13 87

7 15 22

16 11 94

19 8 87

18 3 93

13 13 87

2 1 87

2 6 22

5 20 84

10 12 93

18 12 87

16 10 93

8 17 93

14 7 36

7 4 22

5 9 87

13 10 16

20 11 50

9 16 84

10 17 16

19 6 87

12 2 36

20 9 94

9 2 84

14 1 94

5 5 94

8 17 16

12 8 36

20 17 78

12 18 50

16 8 94

2 19 36

10 18 36

14 19 50

4 12 50

8736

8422

8787

2250

8487

5036

8793

3694

1687

5050

1<=n,m<=100000

1<=a,b,x,y<=n

1<=z<=10^9

在樹上的每個點開一棵權值線段樹, 並且維護區間最大值的大小。

對一條路徑(x,y)進行操作,可以轉化為在x點+1,在y點加1,在lca處減1,在lca的父親那減一。

然後dfs一遍線段樹合併,線段樹上二分查詢答案。

#include #include 

#include

#include

#include

using

namespace

std;

#define reg register inline

intread()

while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48), ch=getchar();

return fu?-res:res;

}#define n 100005

intn, m;

struct

edge ed[n*2

];int

head[n], cnt;

inline

void add(int x, int

y) ;

head[x] =cnt;

}int fa[n][20

], dep[n];

inline

void

bfs()

}}inline

int lca(int x, int

y)int

root[n];

int tr[n*100], ls[n*100], rs[n*100

], tot;

inline

void pushup(int

o)int insert(int l, int r, int o, int p, int

d)

int mid = l + r >> 1

;

if (p <= mid) ls[o] =insert(l, mid, ls[o], p, d);

else rs[o] = insert(mid + 1

, r, rs[o], p, d);

pushup(o);

returno;}

int merge(int l, int r, int a, int

b)

int mid = l + r >> 1

; ls[jd] =merge(l, mid, ls[a], ls[b]);

rs[jd] = merge(mid + 1

, r, rs[a], rs[b]);

pushup(jd);

return

jd;}

void dfs(int x, int

fa)}

int query(int l, int r, int

o)int

main()

bfs();

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

dfs(

1, 0

);

for (reg int i = 1 ; i <= n ; i ++) printf("

%d\n

", query(1, 100000

, root[i]));

return0;

}

bzoj3307 雨天的尾巴

time limit 10 sec memory limit 128 mb submit 258 solved 121 submit status discuss n個點,形成乙個樹狀結構。有m次發放,每次選擇兩個點x,y 對於x到y的路徑上 含x,y 每個點發一袋z型別的物品。完成 所有發放後,每...

BZOJ3307 雨天的尾巴

線段樹合併 在鏈的兩端x,y各打上1個z的加標記,在lca x,y 打上1個z的減標記,在fa lca x,y 打上1個z的減標記,每個節點和所有孩子的線段樹合併,查詢時線段樹上二分 code include include include include include include inclu...

BZOJ3307 雨天的尾巴

bzoj許可權題 良心洛谷 這道題目的花呢,本來想縮先樹剖 可能需要長鏈剖分?再搞乙個標記永久化,然後最後合併答案,不過可能會卡空間。時間複雜度呢是o nlog 2n o n log2 n 然後boshi表示 為什麼不差分然後再自底向上合併線段樹呢 於是就做到了o nlog n o n logn 好...