P3703 SDOI2017 樹點塗色

2022-04-06 12:55:30 字數 2024 閱讀 9691

鏈結分析:

首先對於詢問,感覺是線段樹維護dfs序,每個點記錄到根的顏色個數。第二問差分,第三問區間取max。

那麼考慮修改,每次將乙個點的顏色變成和父節點的顏色一樣的過程中,這個點的子樹內都會-1。

這個修改的過程我們可以認為是修改邊的過程,將一些邊設為1,一些邊設為0,那麼一次修改對於乙個點就是將原來1的邊設為0,現在的邊設為1。

1和0類似lct中實邊與虛邊,所以可以lct維護當前那些邊是1,那些是0。

感覺跟個暴力似的,但是lct中access的操作是log的,所以修改的複雜度是log的,線段樹中再有乙個log,總複雜度是$o(nlog^2)$

**:

#include#include

#include

#include

#include

#include

#include

#include

#include

#include

#define root 1, n, 1

#define lson l, mid, rt << 1

#define rson mid + 1, r, rt << 1 | 1

using

namespace

std;

typedef

long

long

ll;inline

intread()

const

int n = 200005, log = 18

;struct edge e[n << 1

];int head[n], f[n][19

], siz[n], pos[n], deth[n], index, en, n, m;

inline

void add_edge(int u,int

v) void dfs(int

u) }

int lca(int u,int

v) struct

segmenttree

inline

void pushdown(int

rt)

void update(int l,int r,int rt,int l,int r,int

v)

if(tag[rt]) pushdown(rt);

int mid = (l + r) >> 1

;

if (l <=mid) update(lson, l, r, v);

if (r >mid) update(rson, l, r, v);

pushup(rt);

}int query(int l,int r,int rt,int l,int

r)

void pr(int l,int r,int

rt)

if(tag[rt]) pushdown(rt);

int mid = (l + r) >> 1

; pr(lson); pr(rson);

}}t;struct

lct inline

int son(int x)

inline

void rotate(int

x)

void splay(int

x) }

}int find(int

x)

void access(int

x) }

}lct;

intmain()

dfs(1);

for (int j = 1; j <= log; ++j)

for (int i = 1; i <= n; ++i) f[i][j] = f[f[i][j - 1]][j - 1

];

for (int i = 1; i <= n; ++i)

while (m --)

else

}return0;

}

洛谷P3703 樹點塗色

bob 有一棵 n 個點的有根樹,其中 1 號點是根節點。bob 在每個點上塗了顏色,並且每個點上的顏色不同。定義一條路徑的權值是 這條路徑上的點 包括起點和終點 共有多少種不同的顏色。bob 可能會進行這幾種操作 bob 一共會進行 m 次操作。1 leq n leq 10 5 1 leq m l...

SDOI2017 樹點塗色

description bob有一棵n個點的有根樹,其中1號點是根節點。bob在每個點上塗了顏色,並且每個點上的顏色不同。定義一條路 徑的權值是 這條路徑上的點 包括起點和終點 共有多少種不同的顏色。bob可能會進行這幾種操作 1 x 把點x到根節點的路徑上所有的點染上一種沒有用過的新顏色。2 x ...

SDOI2017 樹點塗色

傳送門 塗色的操作和acc es saccess access 很像啊,如何用lct lctlc t維護這個東西呢。由於每次覆蓋的顏色都不同,且是從當前到結點覆蓋到根節點。那麼如果把顏色相同的一段維護在一條重鏈上,乙個點到根要經過多少虛邊也就包含多少顏色。所以用lct lctlc t模擬覆蓋的過程,...