# 長鏈剖分小結

## 概述：

### 長鏈剖分

1.所有重鏈長度之和是\(O(n)\)級別

2.如果x和k次祖先y不在同一重鏈內，那麼y點長鏈的鏈長（所在重鏈末尾節點到它的距離），一定大於等於k

CF1009

``````#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define it set<string>::iterator

const int N1=1e6+7;

template <typename _T> void read(_T &ret)
{
ret=0; _T fh=1; char c=getchar();
while(c<'0'||c>'9'){ if(c=='-') fh=-1; c=getchar(); }
while(c>='0'&&c<='9'){ ret=ret*10+c-'0'; c=getchar(); }
ret=ret*fh;
}
struct EDGE{
void ae(int u,int v)
}e;
int n,ma;
int sz[N1],son[N1],dep[N1],bar[N1],ans[N1];
{
sz[u]=1;
dep[v]=dep[u]+1;
dfs0(v,u);
sz[u]+=sz[v];
if(sz[v]>sz[son[u]]) son[u]=v;
}
}
void push(int x,int w)
{
bar[dep[x]]+=w;
if(bar[dep[x]]>bar[ma]) ma=dep[x];
else if(bar[dep[x]]==bar[ma]&&dep[x]<ma) ma=dep[x];
}
{
push(u,w);
inbar(v,u,w);
}
}
{
int v=e.to[j];
dfs1(v,u);
inbar(v,u,-1);
}
ma=0;
if(son[u]){
dfs1(son[u],u);
}
int v=e.to[j];
inbar(v,u,1);
}
push(u,1);
ans[u]=ma-dep[u];
}

int main(){
// freopen("1.in","r",stdin);
// freopen(".out","w",stdout);
int x,y;
dep[1]=1; dfs0(1,-1);
dfs1(1,-1);
// for(int i=1;i<=n;i++) printf("%d\n",son[i]);
for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
return 0;
}

``````

``````#include<bits/stdc++.h>

using namespace std;

#define ll long long
#define it set<string>::iterator

const int N1=1e6+7;

template <typename _T> void read(_T &ret)
{
ret=0; _T fh=1; char c=getchar();
while(c<'0'||c>'9'){ if(c=='-') fh=-1; c=getchar(); }
while(c>='0'&&c<='9'){ ret=ret*10+c-'0'; c=getchar(); }
ret=ret*fh;
}
struct EDGE{
void ae(int u,int v)
}e;
int n;
int len[N1],son[N1],*f[N1],ans[N1],*tot;
{
dfs0(v,u);
if(len[v]>len[son[u]]) son[u]=v;
}
len[u]=len[son[u]]+1;
}
{
int ma=0;
if(son[u]) f[son[u]]=tot++, ma=dfs1(son[u],u)+1;
f[v]=tot++;
v=dfs1(v,u);
}
for(int i=0;i<len[v];i++){
f[u][i+1]+=f[v][i];
if(f[u][i+1]>f[u][ma]) ma=i+1;
else if(f[u][i+1]==f[u][ma]&&i+1<ma) ma=i+1;
}
}
f[u][0]=1;
if(f[u][0]>f[u][ma]) ma=0;
else if(f[u][0]==f[u][ma]&&0<ma) ma=0;
// ans[u]=ma;
ans[u]=ma;
return ma;
}

int main(){
// freopen("1.in","r",stdin);
// freopen(".out","w",stdout);
int x,y;
dfs0(1,-1);
tot=(int*)malloc(N1*sizeof(int));
f[1]=tot++;
dfs1(1,-1);
// for(int i=1;i<=n;i++) printf("%d\n",son[i]);
for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
return 0;
}

``````