鏈結分析:
首先對於詢問,感覺是線段樹維護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模擬覆蓋的過程,...