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 5view codeusing
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 }
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...