Generally long section + \ (\ RM the DSU \ ON \ Tree \) thinking
Do a conversion, to respect \ (i \ in [1, n-1] \) is determined how many \ (f (u, v) \) satisfies \ (i | f (u, v) \) so that we do a final like inversion
Now we ask how many of \ (f (u, v) \) is \ (i \) or \ (i \) multiples, we need to quickly merge information at the time of the long sides of the cross, this information looks very chic , shaped like the current node distance \ (I \) or \ (I \) number of nodes of the multiple
Fortunately, that son too light, we direct violence harmonic series can handle it, but this information is very bad from where his son inherited
Consider the root partition
If this \ (i> \ sqrt {the n-} \) , which is direct violence severely son where violence complexity is \ (\ FRAC {the n-} {i} <\ sqrt {the n-} \) , so we naturally can directly use long section of the array get when maintenance
But \ (i \ leq \ sqrt { n} \) when considering an array of maintenance can quickly get this information, but such an array heavier son there is no way to inherit, it looks as if the line is not long cross pass
This time you need to use \ (\ rm dsu \) thought the
Consider maintaining a \ (g [i] [j ] \) represents an idea tree internal point depth \ (i \) modulo remainder is \ (j \) the number of points, so we do not need to consider how to inherit like his son did not re-emptied directly used enough
We are very convenient to use this array internal inquiry sub-tree node to the current distance \ (i \) or \ (i \) the number of multiple points, just use the depth of the current point engage in a practice on it
When we light the son of violence can be directly updated \ (G \) , updated every complexity is \ (O (\ sqrt {n }) \) of
But in general, it is the first long section and then re-light the son of the son, but \ (\ rm dsu \) is the son of the first light and then heavy son, here in order to ensure \ (g \) information in the maintenance comes from sub-tree internally, we have to like \ (\ rm dsu \) to treat heavy as the first light after the son of the son
Code
#include<bits/stdc++.h>
#define re register
#define LL long long
#define min(a,b) ((a)<(b)?(a):(b))
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int maxn=2e5+5;
struct E{int v,nxt;}e[maxn];
int n,num,__,B;
int head[maxn],son[maxn],len[maxn],dep[maxn],f[maxn],mu[maxn],p[maxn>>1];
int h[maxn],top[maxn],dfn[maxn],g[320][320],b[maxn],c[maxn];
LL ans[maxn],Ans[maxn];
inline void add(int x,int y) {
e[++num].v=y;e[num].nxt=head[x];head[x]=num;
}
void dfs1(int x) {
for(re int i=head[x];i;i=e[i].nxt) {
dep[e[i].v]=dep[x]+1;dfs1(e[i].v);
if(len[e[i].v]>len[son[x]]) son[x]=e[i].v;
}
len[x]=len[son[x]]+1;
}
void dfs2(int x,int topf) {
top[x]=topf,dfn[x]=++__;
if(!son[x]) return;
dfs2(son[x],topf);
for(re int i=head[x];i;i=e[i].nxt)
if(son[x]!=e[i].v) dfs2(e[i].v,e[i].v);
}
inline void ins(int x,int v) {
for(re int i=1;i<=B;++i) g[i][x%i]+=v;
}
inline int calc(int x,int k) {
if(k<=B) return g[k][dep[x]%k];
int tot=0;
for(re int i=dfn[x]+k;i<=dfn[x]+len[x]-1;i+=k) tot+=h[i];
return tot;
}
void dfs(int x) {
for(re int i=head[x];i;i=e[i].nxt)
if(son[x]!=e[i].v) dfs(e[i].v);
if(son[x]) dfs(son[x]);
for(re int i=head[x];i;i=e[i].nxt) {
if(son[x]==e[i].v) continue;
int y=e[i].v;
for(re int j=1;j<=len[y];++j)
b[j]=h[dfn[y]+j-1];
for(re int j=1;j<=len[y];++j)
for(re int k=j;k<=len[y];k+=j) c[j]+=b[k];
for(re int j=1;j<=len[y];++j)
ans[j]+=1ll*c[j]*calc(x,j);
for(re int j=1;j<=len[y];++j) c[j]=b[j]=0;
for(re int j=1;j<=len[y];++j)
ins(j+dep[y]-1,h[dfn[y]+j-1]),h[dfn[x]+j]+=h[dfn[y]+j-1];
}
ins(dep[x],1);h[dfn[x]]++;
if(x==top[x]) {
for(re int i=1;i<=B;++i)
for(re int j=dep[x];j<=dep[x]+len[x]-1;++j)
g[i][j%i]=0;
}
}
int main() {
n=read();
for(re int x,i=2;i<=n;++i) x=read(),add(x,i);
dep[1]=1,dfs1(1),dfs2(1,1);f[1]=mu[1]=1;
B=std::ceil(std::sqrt(n));B=min(B,310);dfs(1);
for(re int i=2;i<=n;i++) {
if(!f[i]) p[++p[0]]=i,mu[i]=-1;
for(re int j=1;j<=p[0]&&p[j]*i<=n;++j) {
f[p[j]*i]=1;if(i%p[j]==0) break;
mu[p[j]*i]=-mu[i];
}
}
for(re int i=1;i<=n;i++)
for(re int j=i;j<=n;j+=i)
Ans[i]+=1ll*mu[j/i]*ans[j];
for(re int i=2;i<=n;++i)
c[1]++,c[dep[i]]--;
for(re int i=1;i<=n;i++) c[i]+=c[i-1];
for(re int i=1;i<n;i++) printf("%lld\n",Ans[i]+c[i]);
return 0;
}