这道题里需要用到指针.
这里讲一下指针的一些基本操作:
首先,我们要分配一些内存,然后分配一个指针来指向这个内存:
int pp[N],*p=pp,*f[N];
这里指针的空间都会被分配到 pp 里.
假如说我们想给 $f[x]$ 分配一些内存,我们就令 $f[x]=p$,$p leftarrow p+need[x]$.
指针是连续的,也就是说 $f[x]$ 的分配是 $[L_{x},L_{x}+need[x]]$,然后下一次 $p$ 就从 $L_{x}+need[x]+1$ 开始分配内存了.
所以假如调用 $f[x][need[x]+1]$ 的话就会访问到其他数组.
由于长链剖分中对于每一条长链开一个数组就够了,所以我们可以令 $f[son[x]]=f[x]+1$,这样 $f[son[x]]$ 就从 $f[x]$ 的地址+1 开始存储东西了.
总结:注意空间分配就行.
code:
#include <bits/stdc++.h> #define N 1003009 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int edges,n; int pp[N],*p=pp,*f[N],ans[N],son[N],dep[N]; int hd[N],to[N<<1],nex[N<<1]; void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } void dfs1(int x,int ff) { dep[x]=1; for(int i=hd[x];i;i=nex[i]) { int y=to[i]; if(y==ff) continue; dfs1(y,x); if(dep[y]+1>dep[x]) { dep[x]=dep[y]+1; son[x]=y; } } } void dfs2(int x,int ff) { f[x][0]=1; if(son[x]) { f[son[x]]=f[x]+1; dfs2(son[x],x); ans[x]=ans[son[x]]+1; } for(int i=hd[x];i;i=nex[i]) { int y=to[i]; if(y==ff||y==son[x]) continue; f[y]=p,p+=dep[y]; dfs2(y,x); for(int j=1;j<=dep[y];++j) { f[x][j]+=f[y][j-1]; if(f[x][j]>=f[x][ans[x]]) { if(f[x][j]>f[x][ans[x]]) { ans[x]=j; } else if(j<ans[x]) ans[x]=j; } } } if(f[x][ans[x]]==1) ans[x]=0; } int main() { // setIO("input"); scanf("%d",&n); int x,y,z; for(int i=1;i<n;++i) { scanf("%d%d",&x,&y); add(x,y),add(y,x); } dfs1(1,0); f[1]=p,p+=dep[1]; dfs2(1,0); for(int i=1;i<=n;++i) printf("%d ",ans[i]); return 0; }