染色 樹鏈剖分

2021-10-02 14:15:28 字數 2302 閱讀 7840

先樹剖,然後再線段樹維護

考慮對每個節點維護

n um

numnu

m值:表示當前區間顏色段數量

l clc

lc值:表示當前區間最左端的顏色

r crc

rc值:表示當前區間最右端的顏色

合併時,如果左兒子的rc=

=rc==

rc==

右兒子的lclc

lc,那麼合併後父節點的num

numnu

m值還要減一;

查詢時同樣要注意,參見**

#include

#define m 200009

using

namespace std;

int nxt[m]

,to[m]

,first[m]

,tot,n,m,cnt,lc,rc;

int idx[m]

,num[m]

,top[m]

,dep[m]

,f[m]

,a[m]

,size[m]

,son[m]

;struct treetr[m*4]

;int

read()

for(

;isdigit

(ch)

;ch=

getchar()

) re=

(re<<3)

+(re<<1)

+ch-

'0';

return re*f;

}void

add(

int x,

int y)

void

dfs1

(int u,

int fa)

}void

dfs2

(int u,

int tp)

void

pushup

(int k)

void

build

(int k,

int l,

int r)

int mid=

(l+r)

>>1;

build

(k<<

1,l,mid)

;build

(k<<1|

1,mid+

1,r)

;pushup

(k);

}void

change

(int k,

int val)

void

pushdown

(int k)

}void

modify

(int k,

int l,

int r,

int val)

intquery

(int k,

int l,

int r)

void

update

(int x,

int y,

int z)

if(dep[x]

)swap

(x,y)

;modify(1

,num[y]

,num[x]

,z);

}int

solve

(int x,

int y)

if(dep[x]

)swap

(x,y)

,swap

(vis1,vis2)

; ans+

=query(1

,num[y]

,num[x]);

if(vis1==rc) ans--;if

(vis2==lc) ans--

;return ans;

}//void debug(int k)

intmain()

dfs1(1

,0),

dfs2(1

,1);

build(1

,1,n);

for(

int i=

1;i<=m;i++

)else

printf

("%d\n"

,solve

(x,y));

}return0;

}

1,對於該類區間合併時,左右區間相互影響時,考慮本題分多種情況的做

可愛的樹鏈剖分(染色)

這道題 就是 一道 普通的 樹鏈剖分 線段樹覆蓋 注意一下兩個線段樹合併的時候 如果 lva l no de 1 1 rval nod e 1 lval node 1 1 rval node 1 lval n ode 1 1 rval nod e 1 相當於這兩個線段樹的相鄰的數字數相同的 那麼合併...

bzoj 2243 染色 樹鏈剖分

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

HYSBZ 2243 染色 樹鏈剖分

思路 單點的樹鏈剖分題目.大致的思路與邊問題的樹鏈剖分大同小異.只是在處理相鄰的顏色的計算的時候需要仔細.wa了幾發.這邊就寫一下我處理的思路以及記得起來的wa點.理解樹鏈剖分之後,你會明白,樹鏈剖分是按照路徑兩邊往中間縮.所以我用cu,cv標記兩端的顏色.當需要從u開始搜的時候,我就比對一下該端的...