[线段树+][LCA][dfs序][二分查找][×] codeforces 1062E

http://codeforces.com/contest/1062/problem/E

这题两个难点,第一个是如何快速找到一堆不一定在一起的节点的公共LCA,第二个是如何确定这一堆节点中需要剔除哪一个。

可以先想一下,设原集合的lca为p1,可以取得最优答案的点为x,其他点为vi,那么x一定不在lca(所有的vi)这个点的子树上。这时候,任意一个vi和x的lca都是p1。这时假如维护一个S[l,r]表示[l,r]的公共LCA,根据上面说的性质,这个S序列一定存在一个断点,从这个点开始所有的S==p1,这样的话就可以利用二分查找找到这个断点,可以确定这个断点一定是候选答案之一。另外一个在二分的过程中其实是所有的lca都是基于最左边那个点积累过来的,所以除了分界点之外另外一个可能影响到答案的就是最左边这个点。到这里就算是找到了唯二可能影响答案的点,只需要对他们分别验证就可以了。从dalao的代码里学到了lca也可以作为线段树维护的变量。。。 继续阅读“[线段树+][LCA][dfs序][二分查找][×] codeforces 1062E”

[欧拉序][树上线段树][LCA] POJ 2763 Housewife Wind

https://cn.vjudge.net/problem/POJ-2763

欧拉序线段树裸题,每次要求出两点之间的距离,单点修改,区间查询。

欧拉序其实就是把树拍扁的一种方法。。。对给定的树先求出欧拉序,在欧拉序上通过权值的正负来抵消多余的往返操作,然后每次求得时候先求LCA,再求出lca到两个端点的距离相加即可。有了欧拉序LCA就是一个rmq问题,用线段树做就能实现动态求lca,然后端点距离可以用BIT或者仍然用线段树做,求和最后输出即为答案。

实现的主要注意点是下标之间的关系。。。。这其中欧拉序求出来的点个数是2*n-1,然后BIT上存储的又是2n-2个间隔,然后BIT差分又得考虑左端点往前移动一下。。

继续阅读“[欧拉序][树上线段树][LCA] POJ 2763 Housewife Wind”