树链剖分


遍历:

inline void dfs(int u)
{
	sz[u] = 1;
	dep[u] = dep[fa[u]] + 1;
	int v;
	for(int e = hd[u]; e; e = nt[e])
	{
		dfs(v = to[e]);
		sz[u] += sz[v];
		if(sz[v] > sz[son[u]]) son[u] = v;
	}
}

inline void dfs2(int u)
{
	dfn[u] = ++tott; rv[tott] = u;
	top[u] = (son[fa[u]] ^ u) ? u : top[fa[u]];
	int v;
	if(son[u]) dfs2(son[u]); // if(son[u]) very important
	for(int e = hd[u]; e; e = nt[e])
		if((v = to[e]) ^ son[u])
			dfs2(v);
	bot[u] = tott;
}

修改(查询一样):

inline void updatelian(int u, int v, int x)
{
	while(top[u] ^ top[v])
	{
		if(dep[top[u]] < dep[top[v]]) swap(u, v);
		mfy(1, 1, n, dfn[top[u]], dfn[u], x);
		u = fa[top[u]];
	}
	if(dep[u] < dep[v]) swap(u, v);
	mfy(1, 1, n, dfn[v], dfn[u], x);
}

inline void updatetree(int u, int x)
{
	mfy(1, 1, n, dfn[u], bot[u], x);
}

相关