Codechef MXMN
题意
做法一
首先kruskal重构树,那么\(f(G_1/G_2,i,j)\)就转化为\(val[G_1/G_2(lca(i,j))]\)
对\(G_1\)边分,令当前边分出来的边为\((u,v)\),将该边断开,当前连通块分成\(T_1(u),T_2(v)\)
如果在\(G_1\)上\(dep_u<dep_v\),那么\(x\in T_1,y\in T_2,lca(x,y)=lca(x,u)\),否则反之
那么对\(T_1,T_2\)的点分别染上黑/白两色,\(x\in T_1,val_x=val_{lca(x,u)},y\in T_2,val_y=1\)
对于\(T_1\cup T_1\)在\(G_2\)建虚树,对于\(z\in G_2,x\in T_1,y\in T_2,G_2-lca(x,y)=z\),贡献为\(val[G_2(z)]\times val[G_1(x)]\times val[G_1(y)]\),这个很简单搞一个树形dp就好了
\(O(nlogn)\)
做法二
这个做法暂时不太熟练
首先还是建重构树,对于\(G_1\),令\(w(u,fa_u)=val_u-val_{fa_u}\),则\(val_x=dep_x\)
\(dis(x,y)=dep(x)+dep(y)-2dep(lca(x,y))\Longrightarrow dep(lca(x,y))=\frac{1}{2}(dep(x)+dep(y)-dis(x,y))\)
那么对于\(G_2\)上某点\(z\),其两棵子树分别为\(T_1,T_2\),\(x\in T_1,y\in T_2\),贡献为\(val[G_2(z)]\times dep(G_1(lca_{x,y}))=\frac{1}{2}val[G_2(z)]\times G_1(dep(x)+dep(y)-dis(x,y))\)
而\(dep(x),dep(y)\)可以直接根据\(T_1,T_2\)的子树大小直接算出来,只用考虑\(dis(x,y)\)了,对于\(y\in T_2\),\(\forall x\in T_1\)可以通过点分树\(O(logn)\)算出来,然后直接点分树合并就好了。
稍微讲一下点分树合并,开始预处理\(G_1\)的点分树,然后对于每个点\(x\),其初始时点分树为点分树上\(x\)到\(rt\)的路径,合并就跟线段树合并一样。