90pts,在 #5 的时候 WA 了,布吉岛为什么qwq,特来求助各位奆佬棒棒这个萌新
由于没有看题解,所以写得可能有点复杂,请各位见谅
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
namespace Elaina{
#define rep(i, l, r) for(int i=l, i##_end_=r; i<=i##_end_; ++i)
#define fep(i, l, r) for(int i=l, i##_end_=r; i>=i##_end_; --i)
#define fi first
#define se second
#define Endl putchar('\n')
#define writc(x, c) fwrit(x), putchar(c)
typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull;
typedef unsigned int uint;
template<class T>inline T Max(const T x, const T y){return x<y? y: x;}
template<class T>inline T Min(const T x, const T y){return x<y? x: y;}
template<class T>inline T fab(const T x){return x<0? -x: x;}
template<class T>inline void getMax(T& x, const T y){x=Max(x, y);}
template<class T>inline void getMin(T& x, const T y){x=Min(x, y);}
template<class T>T gcd(const T x, const T y){return y? gcd(y, x%y): x;}
template<class T>inline T readin(T x){
x=0; int f=0; char c;
while((c=getchar())<'0' || '9'<c) if(c=='-') f=1;
for(x=(c^48); '0'<=(c=getchar()) && c<='9'; x=(x<<1)+(x<<3)+(c^48));
return f? -x: x;
}
template<class T>void fwrit(const T x){
if(x<0) return putchar('-'), fwrit(-x);
if(x>9) fwrit(x/10); putchar(x%10^48);
}
}
using namespace Elaina;
const int maxn=65534+1;
const int logmaxn=16;
const int maxm=1e6*2;
struct edge{
int to, nxt;
edge(){}
edge(const int T, const int N): to(T), nxt(N){}
}e[maxm+5];
int tail[maxn+5], ecnt;
inline void add_edge(const int u, const int v){
e[ecnt]=edge(v, tail[u]); tail[u]=ecnt++;
}
int n;
// in-degree
int deg[maxn+5];
inline void input(){
n=readin(1);
memset(tail, -1, sizeof tail);
int a;
for(int i=1; i<=n; ++i){
while((a=readin(1))){
add_edge(a, i); // build the reverse edge
++deg[i];
}
}
}
namespace dominant_tre{
vector<int>G[maxn+5];
int tp[maxn+5][logmaxn+5]; // the transfer array
int dep[maxn+5]; // the depth of each node
int rt; // the root of the dominant tree
// initialization
inline void initial(){
// do not use 0 as the root, because empty and root is the same in the array tp[][]
rt=n+1; dep[rt]=1;
}
// add a pair of relationship into dominant tree
inline void add_rela(const int u, const int par){
G[par].push_back(u);
dep[u]=dep[par]+1, tp[u][0]=par;
for(int j=1; j<=logmaxn; ++j)
tp[u][j]=tp[tp[u][j-1]][j-1];
}
// get the lca of two points on the tree
inline int findlca(int u, int v){
if(dep[u]<dep[v]) swap(u, v);
for(int j=logmaxn; j>=0; --j) if(dep[tp[u][j]]>=dep[v])
u=tp[u][j];
if(u==v) return u;
for(int j=logmaxn; j>=0; --j) if(tp[u][j]!=tp[v][j])
u=tp[u][j], v=tp[v][j];
return tp[u][0];
}
int siz[maxn+5];
void dfs(const int u, const int par){
siz[u]=1;
for(int i=0, sz=G[u].size(); i<sz; ++i){
dfs(G[u][i], u);
siz[u]+=siz[G[u][i]];
}
}
}
queue<int>Q;
int lca[maxn+5];
inline void topo(){
dominant_tre::initial();
for(int i=1; i<=n; ++i) if(!deg[i])
lca[i]=dominant_tre::rt, Q.push(i);
while(!Q.empty()){
int u=Q.front(); Q.pop();
dominant_tre::add_rela(u, lca[u]);
for(int i=tail[u], v; ~i; i=e[i].nxt){
v=e[i].to;
if(!lca[v]) lca[v]=u;
else lca[v]=dominant_tre::findlca(lca[v], u);
if(!--deg[v]) Q.push(v);
}
}
}
signed main(){
input();
topo();
dominant_tre::dfs(dominant_tre::rt, 0);
for(int i=1; i<=n; ++i)
printf("%d\n", dominant_tre::siz[i]-1); // except itself
return 0;
}