一个月前打的
今天才调试好。。。
居然是一个SB错误 重建树的深度没有修改。。。
#include<cstdio>
#include<queue>
#include<iostream>
#include<cstring>
using namespace std;
char c;
inline void read(int &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
struct Chain
{
int u;bool Check;
Chain *next;
}*Head[200001],*Cp[200001];
inline void Add(int u,int v)
{
Chain *tp=new Chain;tp->next=Head[u];tp->u=v;Head[u]=tp;tp->Check=false;
}
inline void Add2(int u,int v)
{
Chain *tp=new Chain;tp->next=Cp[u];tp->u=v;Cp[u]=tp;tp->Check=false;
}
bool Check[200001];
int F[200001][21],f[200001],Dep[200001];
inline int LCA(int a,int b)
{
if(a==0||b==0)return a+b;
int j;
while(Dep[a]^Dep[b])
{
if(Dep[a]<Dep[b])swap(a,b);
for(j=0;Dep[F[a][j+1]]>Dep[b];j++);
a=F[a][j];
}
while(a^b)
{
for(j=0;F[a][j+1]^F[b][j+1];j++);
a=F[a][j],b=F[b][j];
}
return a;
}
inline void DFS(int u)
{
Check[u]=true;
for(Chain *tp=Head[u];tp;tp=tp->next)
if(!Check[tp->u])
f[tp->u]=u,F[tp->u][0]=0,Dep[tp->u]=Dep[u]+1,DFS(tp->u),tp->Check=true;
}
int Du[200001];
bool Done[200001];
queue<int>Q;
inline void Cl(int x)
{
Dep[x]=Dep[F[x][0]]+1;
for(int j=1;j<=20;j++)F[x][j]=F[F[x][j-1]][j-1];}
int Cu[200001],Dgr[200001];
int main()
{
int n,m;read(n);m=n+1;
for(int i=1;i<=n;i++)
{
while(true)
{
int j;
read(j);
if(!j)break;
Du[i]++;
Add(j,i);Add2(i,j);
Cu[j]++;
}
}
for(int i=1;i<=n;i++)
if(Du[i]==0)Add(m,i),Add2(i,m),Cu[m]++,Du[i]++;
DFS(m);
F[m][0]=m;
Cl(m);
f[m]=m;
Q.push(m);
int sp,t=0;
while(!Q.empty())
{
int u=Q.front();
Q.pop();
Cl(u);
for(Chain *tp=Head[u];tp;tp=tp->next)
{
if(tp->u==31)
u++,u--;
sp=LCA(u,F[tp->u][0]);
F[tp->u][0]=sp;
// Cl(F[tp->u][0]);
Du[tp->u]--;
if(!Du[tp->u])Q.push(tp->u);
}
}
for(int i=1;i<=n;i++)
if(!Cu[i])Q.push(i);
while(!Q.empty())
{
int u=Q.front();
Q.pop();
for(Chain *tp=Cp[u];tp;tp=tp->next)
{
Cu[tp->u]--;
if(!Cu[tp->u])
Q.push(tp->u);
}
Dgr[F[u][0]]+=Dgr[u]+1;
}
for(int i=1;i<=n;i++)
printf("%d\n",Dgr[i]);
return 0;
}