树链剖分

void dfs1(int x)
{
	sz[x]=1;
	for(int i=b[x];i;i=nxt[i])
	{
		if(to[i]==f[x])
			continue;
		f[to[i]]=x;
		dep[to[i]]=x;
		dep[to[i]]=dep[x]+1;
		dfs1(to[i]);
		sz[x]+=sz[to[i]];
		if(sz[to[i]]>sz[son[x]])
			son[x]=to[i];	
	}	
}

void dfs2(int x,int y)
{
	top[x]=y;
	id[x]=++tot;
	if(son[x])
		dfs2(son[x],y);
	for(int i=b[x];i;i=nxt[i])
	{
		if(to[i]==f[x]||to[i]==son[x])
			continue;
		dfs2(to[i],to[i]);
	}
}

int query(int x,int y)
{
	int ans=0;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		ans+=get(id[top[x]],id[x]);
		x=f[top[x]];
	}
	if(dep[x]<dep[y])
		swap(x,y);
	ans+=get(id[y],id[x]);
	return ans;
} 

题目推荐

1.P3313 SDOI2014 旅行

2.P2680 运输计划

posted on 2020-07-23 20:09  Allen_lml  阅读(114)  评论(0编辑  收藏  举报