bzoj3307 雨天的尾巴 線段樹合併

2021-08-20 05:43:13 字數 3064 閱讀 5014

description

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

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

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

input

第一行數字n,m

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

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

output

輸出有n行

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

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

則輸出0

sample input

20 50

8 6

10 6

18 6

20 10

7 20

2 18

19 8

1 6

14 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

sample output

87 36

84 22

87 87

22 50

84 87

50 36

87 93

36 94

16 87

50 50

1<=n,m<=100000

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

1<=z<=10^9

hint

source

直接考慮差分一下即可 即每個點儲存1到這個點的所有資訊 如x,y需要改那麼則在x上+1 y上+1

lca-1 fa[lca]-1即可 然後最後合併的時候從底向上合併即可 這個差分可以看做 這個點到跟的路徑分別被差分了一下

線段樹合併乙個log竟然如此慢

另外記憶體不太會算qwq總覺得應該是120*n

#include

#include

#include

using namespace std;

inline char gc()

return

*s++;

}inline int

read()

while(isdigit(ch)) x=x

*10+ch-'0',ch=gc();

return

x*f;

}const int n=1e5+10;

struct nodedata[n<<1];

int n,h[n],dep[n],log[n],fa[n][20],rt[n],ans[n],num,m;

inline void dfs(intx)}

inline int lca(int

x,int

y)struct node1tree[n*60];

inline void update(int

x)inline void insert1(int &x,int l,int r,int p,int v)

if(p<=mid) insert1(tree[x].left,l,mid,p,v);

else insert1(tree[x].right,mid+1,r,p,v);update(x);

}inline int merge(int rt1,int rt2,int l,int r)int mid=l+r>>1;

tree[rt1].left=merge(tree[rt1].left,tree[rt2].left,l,mid);

tree[rt1].right=merge(tree[rt1].right,tree[rt2].right,mid+1,r);update(rt1);return rt1;

}const int nn=1e9;

inline void print(int

x,int l,int r)

inline void dfs1(int

x)ans[x]=tree[rt[x]].id;

}int main()dfs(1);num=0;

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

for (int i=1;i<=n;++i) printf("%d\n",ans[i]);

return

0;}

bzoj 3307 雨天的尾巴 線段樹

n個點,形成乙個樹狀結構。有m次發放,每次選擇兩個點x,y 對於x到y的路徑上 含x,y 每個點發一袋z型別的物品。完成 所有發放後,每個點存放最多的是哪種物品。1 n,m 100000 1 a,b,x,y n 1 z 10 9 比較巧妙的一道題。考慮如果是在一條鏈上的話要怎麼做。那麼我們可以在x處...

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...