BZOJ2243 樹鏈剖分 線段樹)

2022-08-05 16:03:16 字數 2488 閱讀 9237

problem 染色(bzoj2243)

題目大意

給定一顆樹,每個節點上有一種顏色。

要求支援兩種操作:

操作1:將a->b上所有點染成一種顏色。

操作2:詢問a->b上的顏色段數量。

解題分析

樹鏈剖分+線段樹。

開乙個記錄型別,記錄某一段區間的資訊。l 表示區間最左側的顏色 , r 表示區間最右側的顏色 , sum 表示區間中顏色段數量。

合併時判斷一下左區間的右端點和有區間的左端點的顏色是否一樣。

樹上合併時需要用兩個變數ans1,ans2來儲存。ans1表示x往上走時形成的鏈的資訊,ans2表示y往上走時形成鏈的資訊。

當x和y位於同一條重鏈上時,有三個區間需要合併在一起,注意判斷順序。

參考程式

1 #include 2 #include 3 #include 4 #include 5

using

namespace

std;67

#define v 100008

8#define e 200008

9#define lson l,m,rt<<1

10#define rson m+1,r,rt<<1|1

1112

intn,m,cnt;

13int

a[v],size[v],dep[v],fa[v],son[v],top[v],w[v],rk[v];

1415

struct

lineeg[e];

18int

sum,lt[v];

1920

struct

color

23};

24color merge(color a,color b)

33else

3439

return

c;40}41

42struct

segment_tree

48void pushdown(int

rt)57}58

void build(int l,int r,int

rt)64

int m=(l+r)/2;65

build(lson);

66build(rson);

67pushup(rt);68}

69void update(int l,int r,int val,int l,int r,int

rt)76

pushdown(rt);

77int m=(l+r)/2;78

if (l <=m) update(l,r,val,lson);

79if (m

80pushup(rt);81}

82 color query(int l,int r,int l,int r,int

rt)86

pushdown(rt);

87color res;

88int m=(l+r)/2;89

if (l <= m) res=merge(res,query(l,r,lson));

90if (m < r) res=merge(res,query(l,r,rson));

91return

res;92}

93}t;

9495

void adt(int u,int

v)98

void add(int u,int

v)101

102void dfs_1(int

u)112

}113

void dfs_2(int u,int

tp)121

}122

void change(int x,int y,int

val)

128if (dep[x]>dep[y]) swap(x,y);

129 t.update(w[x],w[y],val,1,n,1

);130

}131

void

pt(color a)

134void find(int x,int

y)141

else

142146

147}

148if (dep[x]

154else

155161 printf("

%d\n

",ans.sum );

162}

163164

intmain()

173 dfs_1(1

);174 dfs_2(1,1

);175 t.build(1,n,1

);176

while (m--)

184else

185;

189}

190 }

view code

BZOJ 2243 樹鏈剖分 線段樹

include define n 101000 define frei freopen in.txt r stdin define freo freopen out.txt w stdout define mem a,b memset a,b,sizeof a define lson root 1 ...

bzoj2243染色 樹鏈剖分 線段樹

time limit 20 sec memory limit 512 mb submit 8230 solved 3073 submit status discuss 給定一棵有 n個節點的無根樹和 m個操作,操作有2類 1 將節點 a到節點 b路徑上所有點都染成顏色c 2 詢問節點 a到節點 b路...

bzoj2243 染色 樹鏈剖分 線段樹

解題思路 先鏈剖。維護線段樹時每個節點維護三個值 lc 左端點顏色 rc 右端點顏色 cnt 區間中顏色段數量 注意每次合併區間時 詳見 中update,query,query函式 若左區間rc等於右區間lc是結果要減1 修改時打標記即可,注意tag初始要賦值為 1,因為有color為0的情況。in...