void dfs1(){
// 求出重儿子
}
void add(){
// 加入一个节点的贡献
}
void del(){
// 删去一个节点的贡献
}
void insert(int u){
// 加入整棵子树的贡献
add(u);
for(int i=head[u],v;i;i=e[i].nxt){
v=e[i].to;
if(v==fa[u]) continue;
insert(v);
}
}
void erase(int u){
// 删去整棵子树的贡献
del(u);
for(int i=head[u],v;i;i=e[i].nxt){
v=e[i].to;
if(v==fa[u]) continue;
erase(v);
}
}
void dfs2(int u){
// 递归处理轻儿子答案
for(int i=head[u],v;i;i=e[i].nxt){
v=e[i].to;
if(v==fa[u]||v==son[u]) continue;
dfs2(v);
}
// 递归处理重儿子答案
if(son[u]) dfs2(son[u]);
// 重新遍历轻儿子子树,计算当前子树的答案
add(u);
for(int i=head[u],v;i;i=e[i].nxt){
v=e[i].to;
if(v==fa[u]||v==son[u]) continue;
insert(v);
}
// 如果当前节点是轻儿子,重新遍历整棵子树,清除答案
if(fa[u]&&son[fa[u]]!=u) erase(u);
}