bzoj2243染色 樹鏈剖分 線段樹

2021-08-07 10:25:13 字數 2660 閱讀 9088

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路徑上的顏色段數量(連續相同顏色被認為是同一段),如「

112221」由

3段組成:「11」

、「222」和「

1」。請你寫乙個程式依次完成這

m個操作。

第一行包含

2個整數n和

m,分別表示節點數和運算元;

第二行包含

n個正整數表示

n個節點的初始顏色

下面行每行包含兩個整數x和

y,表示x和

y之間有一條無向邊。

下面行每行描述乙個操作:

「c a b c」

表示這是乙個染色操作,把節點

a到節點

b路徑上所有點(包括a和

b)都染成顏色c;

「q a b」

表示這是乙個詢問操作,詢問節點

a到節點

b(包括a和

b)路徑上的顏色段數量。

對於每個詢問操作,輸出一行答案。

6 52 2 1 2 1 1

1 21 3

2 42 5

2 6q 3 5

c 2 1 1

q 3 5

c 5 1 2

q 3 531

2數n<=10^5,運算元m<=10^5,所有的顏色c為整數且在[0, 10^9]之間。

第一輪day1

樹鏈剖分,用線段樹維護每段上的顏色數量以及左右端點上的顏色,合併時看左右端點顏色是否相同,不同左右相加否則減一

然後區間修改

注意跳輕鏈的時候要特判一下鏈頭和跳過去的節點顏色是否相同,如果相同要把答案減一。判的時候用線段樹判,因為這是修改過後的線段樹

#include#include#include#include#include#include#include#define maxn 101000

#define inf 0x3f3f3f3f

#define ls p << 1

#define rs p << 1 | 1

using namespace std;

int read()

while(ch >= '0' && ch <= '9')

return x * f;}

struct tree

}t[maxn * 10];

int pre[maxn], top;

struct edge

}e[maxn * 2];

void adds(int u, int v)

int n, m, tot, sz;

int w[maxn], f[maxn], d[maxn], pos[maxn], deep[maxn], son[maxn], fw[maxn];

int lca(int u, int v)

if(deep[u] > deep[v]) swap(u, v);

return u;}

void dfs1(int u, int fa)}

void dfs2(int u, int chain)

if(!k) return;

dfs2(k, chain);

for(int i = pre[u]; ~i; i = e[i].next)

} void update(int p)

void build_tree(int p, int l, int r)

int mid = l + r >> 1;

build_tree(ls, l, mid);

build_tree(rs, mid + 1, r);

update(p);}

void init()

void paint(int p, int val)

void pushdown(int p) }

void seg_ch(int p, int st, int ed, int val)

int mid = l + r >> 1;

pushdown(p);

if(st <= mid) seg_ch(ls, st, min(mid, ed), val);

if(ed > mid) seg_ch(rs, max(st, mid + 1), ed, val);

update(p);}

void change(int u, int v, int val)

if(pos[u] > pos[v]) swap(u, v);

seg_ch(1, pos[u], pos[v], val);}

int seg_sum(int p, int st, int ed)

int seg_col(int p, int pos)

int query(int u, int v)

if(pos[u] > pos[v]) swap(u, v);

//cout<

bzoj2243 染色 樹鏈剖分 線段樹

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

bzoj 2243 染色 樹鏈剖分

首先這是個挺裸的題,由於太久沒寫剖分導致調了好久,前天調了一下午,一直查不到錯 昨晚在看春晚的時候突然靈機一動,發現合併的時候出了問題,開電腦把它a掉了 感覺自己也蠻拼的給定 一棵有n 個節點的 無根樹和 m個操作 操作有 2類 1 將節點a 到節點b 路徑上所 有點都染 成顏色c 2 詢問節點a ...

bzoj 2243 樹鏈剖分 染色

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