树链剖分
作者:互联网
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