树上 lca查分讲解<-------------------------
个人觉得,和普通的查分没有什么区别。
注意一点,chafen数组的定义
1---.点的差分
接下来所有“子节点”指“ 直系子节点”!!!!直系子节点指的是和父节点有一条边直接相连的子节点。
chafen[ maxn ]:差分数组,定义 当前节点 与其子树的总和之差 (子树指的是直系子节点)
eg.
for(int i=1,u,v;i<=k;i++)
{
u=read();v=read();
int loc=lca(u,v);
num[u]++;
num[v]++;
num[loc]--;
num[f[loc][0]]--;
}
2---.边的差分
显然边比较难统计,可以把边转化到点上,即某个点uu存储(u,father[u])(u,father[u])这条边。
eg.
for(int i=1;i<n;i++)
{
int a=i,b=i+1;
int loc=lca(a,b);
num[a]++;num[b]++;
num[loc]-=2;
}
3---.最后的加权
点:
inline void getans(int x,int fa)
{
for(int i=head[x];i;i=e[i].next)
{
int nx=e[i].to;
if(nx==fa) continue;
getans(nx,x);
num[x]+=num[nx];
}
}
边:
inline void getans(int x,int fa)
{
int tmp=0;
for(int i=head[x];i;i=e[i].next)
{
int nx=e[i].to;
if(nx==fa)
{
tmp=i;
continue;
}
getans(nx,x);
num[x]+=num[nx];
}
if(e[tmp].c1*num[x]>e[tmp].c2)
{
ans+=e[tmp].c2;
}
else
{
ans+=e[tmp].c1*num[x];
}
}