Description
给一棵$n$个点的有标号无根树,你需要找到满足条件的路径$u−v$的条数。
我们称路径$u-v$满足条件当且仅当$u\not=v$且路径$u-v$上不存在点对
$(a,b)$,$a,b$满足$gcd(a,b)=a$。
注意:路径$u−v$和$v−u$是同一条路径。
Input
第一行一个整数$n\le10^5$
接下来$n−1$行,每行两个用空格隔开的整数$a,b$,表示边$(a,b)$
Output
一行一个整数,代表要求的答案。
Sample Input
4
3 1
3 2
3 4
Sample Output
2
//只有路径$2 − 3$和$3 − 4$满足条件
Solution
这个题的转换很有意思
我们考虑用总路径数-不合法的路径数来得到合法的路径数
那么现在问题就在于,如何求不合法的路径数
首先根据题意,枚举起点$u$,可以通过枚举$u$的倍数来得到一些不合法的路径,我们可以称之为“限制”,很容易得出:每一个不合法的路径必定至少包含一个“限制”
知道这个有什么用呢?
重头戏来了:
设$dfn[x]$为$x$点的dfs序,$cover[x]$为$x$子树中最大的dfs序
考虑不合法路径$a-b$,假设$a-b$包含路径$u-v$且$dfn[u]<dfn[v]$,$dfn[a]<dfn[b]$
分两种情况讨论:
- $u$是$v$的一个祖先
- $u$不是$v$的祖先
对于第一种情况
这时候$a,b$和$u,v$有怎样的关系呢?我们来看下面这张图
这时我们发现,$a$可以是$g$子树外的任意一点,$b$可以是$v$子树内的任意一点,他们对应的dfs序关系为
$dfn[a]$ $<$ $dfn[g]\;\;and\;\;dfn[v]\le dfn[b] \le cover[v]$
当然你可能会问:那如果我们先遍历图中$g$的那棵子树,上面这个关系就不成立了!(注意我们的前提条件,$a$的dfs序小于$b$)
没错,所以我们还要讨论把上图中把$a,b$交换的情况,此时关系为
$dfn[v]\le dfn[a] \le cover[v]\;\;and\;\;dfn[b] > cover[g]$
对于第二种情况
这种情况相对较简单,还是先上图
此时$a$是$u$子树中的任意一点,$b$是$v$子树中的任意一点
所以对应的关系就是
$dfn[u]\le dfn[a] \le cover[u]\;\;and\;\;dfn[v]\le dfn[b]\le cover[v]$
说了这么多,这有什么用啊?
考虑这样一个坐标系
这个坐标系的横轴是$dfn[a]$,纵轴是$dfn[b]$
再看看上面我们列出的条件,$dfn[a]$对应一个横轴上的区间,$dfn[b]$对应一个纵轴上的区间
这不是矩形嘛!
大致乱画一下,其实一堆条件(关系)就成了下面这个东西
这些矩形内的每一个整点$(dfn[a],dfn[b])$,都是满足我们要求的东西,也就是不合法
而每一个dfs序对应唯一节点,这样我们计算这些矩形内的整点个数就能得到不合法的路径数
如何计算?线段树维护扫描线即可,只不过把求面积改成求矩形内点的个数,如果具体不清楚可以直接看代码,代码还算是比较简明的
最终统计答案,由于我们这样求出的路径是无向的,设求出的路径数为$ans$
答案就是$\dfrac{n*(n-1)}{2}-ans$
复杂度:枚举$u,v$是$O(n\ln n)$的,线段树还要再乘个$\log n$,所以总复杂度应该是$O(n\ln n\log n)$
最后献上本人丑陋的代码,现在是2019年3月28日22:06:10,目前在BZOJ是最快的代码
1 | /************************************************************** |