树链剖分的一个小细节

做树链剖分最头疼的就是LCA的特殊性,有必要自己证明一下,否则用着不踏实,以求x到y的sum为例,z=lca(x,y)

procedure solvesum;
 begin
   ans:=0;
   while ch<>' ' do read(ch);
   readln(x,y);
     while top[x]<>top[y] do
     begin
      if dep[top[x]]<dep[top[y]] then swap(x,y);
      inc(ans,getsum(1,p[top[x]],p[x]));
      x:=fa[top[x]];
     end;
   if dep[x]>dep[y] then swap(x,y);
   inc(ans,getsum(1,p[x],p[y]));
   writeln(ans);
 end;

一个显而易见的结论是 若x处于y的子树中,那么dep[top[x]]<=dep[top[y]]当且仅当top[x]=top[y]即x,y处于同一条重链上=成立

1.若 top[x]=top[y] 说明x,y在同一条重链上,求和sum(p[x],p[y])即可 (p[x]<p[y])

2.若top[x]!=top[y]且x,y都不在z向下的重链上,那么往上提的时候一定有一个点不妨设为x通过x=fa[top[x]]操作到达z的重链上,并且没有计算这条链上的贡献

   这样dep[top[x]]达到最小值,x不会再往上提,直到另一个节点通过同样的操作到达z的重链上,并且没有计算,

   这时候必有x,y之一=z,dep值小的就是LCAz

   这时候退出while,在外层ans+=sum(p[x],p[y])即可,p[x]<p[y]

3.若top[x]!=top[x]且x,y中有一个处于以z向下的重链上,不妨设为x,那么一开始dep[top[x]]达到最小值,只会调整y,直到y通过fa[top[y]]到达z的重链上

   此时也没有计算z的重链,退出while之后计算即可类似于2计算即可

忽然发现自己写了这么多证了一个多么sb的问题。。。

所以貌似 月下毛景树那一题也可以不求LCA搞,去试试。。。。

总之归根结底就是一句话:

退出while之后 dep小的就是x和y的LCA,并且它的信息还没有被计算过!!!

 

posted @ 2014-08-22 09:25  ZYF-ZYF  Views(202)  Comments(0Edit  收藏  举报