其他分享
首页 > 其他分享> > 树链剖分

树链剖分

作者:互联网

LCA

struct Edge{
	int v,nxt;
}edge[maxn];
int head[maxn],tot=0;
inline void read(int &x){
	x=0;char tmp=getchar();
	while(tmp<'0'||tmp>'9')tmp=getchar();
	while(tmp>='0'&&tmp<='9')x=(x<<1)+(x<<3)+tmp-'0',tmp=getchar();
}
inline void add_edge(int x,int y){
	edge[tot].v=y,edge[tot].nxt=head[x],head[x]=tot++;
}
int dep[maxn],sz[maxn],son[maxn],fa[maxn];
int top[maxn],id[maxn],dfs_clock=0;
void dfs1(int u,int depth){
	dep[u]=depth,sz[u]=1,son[u]=-1;
	for(int i=head[u];i!=-1;i=edge[i].nxt){
		int v=edge[i].v;
                if(dep[v])continue;
		fa[v]=u;
		dfs1(v,depth+1);
		sz[u]+=sz[v];
		if(son[u]==-1||sz[v]>sz[son[u]])son[u]=v;
	}
}
void dfs2(int u,int tp){
	top[u]=tp,id[u]=++dfs_clock;
	if(son[u]==-1)return;
	dfs2(son[u],tp);
	for(int i=head[u];i!=-1;i=edge[i].nxt){
		int v=edge[i].v;
		if(v!=son[u]&&v!=fa)
			dfs2(v,v);
	}
}
int lca(int x,int y){//也可以swap不过这个常数小点
	if(y>n)return 0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])y=fa[top[y]];
		else x=fa[top[x]];
	}
	if(dep[x]<dep[y])return x;
	else return y;
}

链/子树上操作

struct Edge{
	int v,nxt;
}edge[maxn];
int head[maxn],tot=0;
inline void read(int &x){
	x=0;char tmp=getchar();
	while(tmp<'0'||tmp>'9')tmp=getchar();
	while(tmp>='0'&&tmp<='9')x=(x<<1)+(x<<3)+tmp-'0',tmp=getchar();
}
inline void add_edge(int x,int y){
	edge[tot].v=y,edge[tot].nxt=head[x],head[x]=tot++;
}
int dep[maxn],sz[maxn],son[maxn],fa[maxn];
int top[maxn],id[maxn],dfs_clock=0;
void dfs1(int u,int depth){
	dep[u]=depth,sz[u]=1,son[u]=-1;
	for(int i=head[u];i!=-1;i=edge[i].nxt){
		int v=edge[i].v;
                if(dep[v])continue;
		fa[v]=u;
		dfs1(v,depth+1);
		sz[u]+=sz[v];
		if(son[u]==-1||sz[v]>sz[son[u]])son[u]=v;
	}
}
void dfs2(int u,int tp){
	top[u]=tp,id[u]=++dfs_clock;
	if(son[u]==-1)return;
	dfs2(son[u],tp);
	for(int i=head[u];i!=-1;i=edge[i].nxt){
		int v=edge[i].v;
		if(v!=son[u]&&v!=fa)
			dfs2(v,v);
	}
}

标签:tmp,剖分,int,tp,son,dfs2,edge,树链
来源: https://www.cnblogs.com/xyc1719/p/16096741.html