int fa[maxn][maxlg]; int dep[maxn]; int dif[maxn]; int sum[maxn]; int n; vector<int> adj[maxn];
voiddfs( int u, int father ) { fa[u][0] = father; dep[u] = dep[father] + 1; for( int v : adj[u] ) { if( v != father ) dfs( v, u ); } return ; }
voidstInit( ) { for( int j = 1; j < maxlg; ++ j ) for( int i = 1; i <= n; ++ i ) fa[i][j] = fa[ fa[i][j-1] ][j-1]; return ; }
intgetlca( int u, int v ) { if( dep[u] < dep[v] ) swap( u, v ); int diff = dep[u] - dep[v]; for( int i = 0; (1 << i) <= diff; ++ i ) { if( (1 << i) & diff ) u = fa[u][i]; } if( u == v ) return u; for( int i = maxlg - 1; i >= 0; -- i ) { if( fa[u][i] != fa[v][i] ) { u = fa[u][i]; v = fa[v][i]; } } return fa[u][0]; }
voidgetsum( int u, int father ) { sum[u] = dif[u]; for( int v : adj[u] ) { if( v != father ) { getsum( v, u ); sum[u] += sum[v]; } } }