SDOI2011 染色 樹鏈剖分

2021-10-02 10:52:08 字數 3306 閱讀 5422

題目鏈結

有一棵n個節點的樹,每個節點有顏色,支援兩種操作:

樹上的鏈操作擺明了要用樹鏈剖分.用線段樹來維護資訊.

線段樹的每個節點需要儲存,區間的顏色數量,以及區間左端點的顏色和右端點的顏色.

以下是線段樹中特殊操作

先把左右兒子的顏色段數加起來.如果左兒子的右端點和右兒子的左端點是同一種顏色,那麼顏色段數-1

void

pushup

(int k)

詢問返回乙個pair> 型別的元素, 表示區間的顏色段樹,以及左右端點的顏色.

合併答案的時候同樣按照向上更新節點的方式合併

pair<

int,pii>

query

(int l,

int r,

int k)

pushdown

(k);

int mid=

(l[k]

+r[k]

)>>1;

if(mid>=l)

if(midreturn ans;

}

我們將鏈的端點定義問左節點和右節點.將左節點到lca定義為左鏈,將lca到右節點定義為左鏈.

分別計算左鏈和右鏈的答案,最後再合併到一起.

pair<

int,pii>

getsum

(int l,

int r)

else}if

(dep[l]

>dep[r]

)else

ansl.fi+

=ansr.fi;

if(ansl.se.fi==ansr.se.fi) ansl.fi--

;return ansl;

}

#include

using

namespace std;

typedef

long

long ll;

typedef

unsigned

long

long ull;

typedef pair<

int,

int> pii;

#define pb push_back

#define fi first

#define se second

#define rep(i,a,b) for(int i=(a);i<=(b);i++)

#define per(i,a,b) for(int i=(a);i>=(b);i--)

const

int maxn=

1e5+10;

const

int mod=

1e9+7;

const

int inf=

0x3f3f3f3f

;int dep[maxn]

,son[maxn]

,size[maxn]

,tp[maxn]

,fa[maxn]

,book[maxn]

;int id[maxn]

,rk[maxn]

,cnt=0;

vector<

int> g[maxn]

;void

dfs1

(int now,

int f,

int d)

}void

dfs2

(int now,

int t)

}struct segmenttree

void

build

(int l,

int r,

int k)

int mid=

(l+r)

>>1;

build

(l,mid,k<<1)

;build

(mid+

1,r,k<<1|

1);pushup

(k);

}void

pushdown

(int k)

void

change

(int l,

int r,

int k,

int x)

pushdown

(k);

int mid=

(l[k]

+r[k]

)>>1;

if(mid>=l)

change

(l,r,k<<

1,x);if

(midchange

(l,r,k<<1|

1,x)

;pushup

(k);

} pair<

int,pii>

query

(int l,

int r,

int k)

pushdown

(k);

int mid=

(l[k]

+r[k]

)>>1;

if(mid>=l)

if(midreturn ans;

}}tree;

void

output

(pair<

int,pii>x)

pair<

int,pii>

getsum

(int l,

int r)

else}if

(dep[l]

>dep[r]

)else

ansl.fi+

=ansr.fi;

if(ansl.se.fi==ansr.se.fi) ansl.fi--

;return ansl;

}void

change

(int l,

int r,

int c)

if(dep[l]

>dep[r]

)swap

(l,r)

; tree.

change

(id[l]

,id[r],1

,c);

}int

main()

dfs1(1

,0,1

);dfs2(1

,1);

tree.

build(1

,n,1);

while

(m--

)else

if(ty==

'q')

}return0;

}

SDOI 2011 染色 樹鏈剖分

題意 給定一棵有n個節點的無根樹和m個操作,操作有2類 1 將節點a到節點b路徑上所有點都染成顏色c 2 詢問節點a到節點n路徑上的顏色段數量 連續相同顏色被認為是同一段 如 112221 由3段組成 11 222 和 1 n,m 100000 思路 樹的形態沒有改變,用樹鏈剖分維護即可。pre1,...

SDOI2011 染色 樹鏈剖分

輸入格式 輸出格式 對於每個詢問操作,輸出一行答案。輸入樣例 1 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 5 輸出樣例 1 31 怎麼實現建樹操作呢,我們需要兩個陣列s和t,代表當前操作區間的左端點的顏色和右端點...

SDOI2011 染色 題解

題目大意 給定一棵有n個節點的無根樹和m個操作,操作有2類 1 將節點a到節點b路徑上所有點都染成顏色c 2 詢問節點a到節點b路徑上的顏色段數量 連續相同顏色被認為是同一段 思路 樹剖之後,維護其兩端的顏色 答案和標記即可。include include define n 100001 using...