!-- Loading 底层遮罩 -->

树链剖分

剖分过程

void dfs1(int u)
{
	son[u] = -1;
	siz[u] = 1;
	for (int i = hd[u]; i; i = g[i].nxt)
	{
		int v = g[i].to;
		if (!dep[v])
		{
			dep[v] = dep[u] + 1;
			fa[v] = u;
			dfs1(v);
			siz[u] += siz[v];
			if (son[u] == -1 || siz[v] > siz[son[u]])
				son[u] = v;
		}
	}
	return;
}
void dfs2(int u, int t)
{
	top[u] = t;
	dfcnt++;
	dfn[u] = dfcnt;
	rdfn[dfcnt] = u;
	if (son[u] == -1)
		return;
	dfs2(son[u], t);
	for (int i = hd[u]; i; i = g[i].nxt)
	{
		int v = g[i].to;
		if (v != son[u] && v != fa[u])
			dfs2(v, v);
	}
	return;
}

跳链过程

更新

{
    while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]])
			swap(x, y);
		update(1, 1, n, dfn[top[x]], dfn[x], z);
		x = fa[top[x]];
	}
	if (dep[x] > dep[y])
		swap(x, y);
	update(1, 1, n, dfn[x], dfn[y], z);
}

 求和

{
    ll ans = 0;
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]])
			swap(x, y);
		ans += query(1, 1, n, dfn[top[x]], dfn[x]);
		x = fa[top[x]];
	}
	if (dep[x] > dep[y])
		swap(x, y);
	ans += query(1, 1, n, dfn[x], dfn[y]);
}

 

posted @ 2022-10-28 11:36  Thinker-X  阅读(46)  评论(0)    收藏  举报