我们把每个村子的结果拆开应该变成一堆和的形式。
(Ci×ai×bi+Ci×bi×xi+Ci×ai×yi+Ci×xi×yi).
我们从叶子到根维护前缀和,直接求不行吗?
inline void dfs(int t){
if(t>=n)return;
int x=0,y=0;
for(int i=hea[t];i;i=nex[i]){
int v=ver[i];x?y=v:x=v;
dfs(v);
f[t].c+=f[v].c;f[t].ca+=f[v].ca;
f[t].cb+=f[v].cb;f[t].s+=f[v].s;
f[t].cx+=f[v].cx;f[t].cy+=f[v].cy;
}
ll k1,k2;
k1=!f[y].op?f[y].cb+f[y].cy:f[y].ca+f[y].cx;
k2=!f[x].op?f[x].cb+f[x].cy:f[x].ca+f[x].cx;
if(k1<k2){
f[t].s+=k1;
if(!f[y].op)f[t].cx+=f[y].c;else f[t].cy+=f[y].c;
}
else{
f[t].s+=k2;
if(!f[x].op)f[t].cx+=f[x].c;else f[t].cy+=f[x].c;
}