codechef TREECNT2

设\(\gcd(l...r)\)表示\(l...r\)路径上的\(\gcd\)
\(ans=[\gcd(l...r)]=\sum_{d|\gcd(l...r)}vu(d)\)
\(=\sum_{i=1}^{1000000}vu(d)\sum_{d|\gcd(l...r)}1\)
一个显然的想法:注意到只有\(vu(d)\neq 0\)且被一个\(\gcd(l...r)\)整除的\(d\)才有用。
所以可以把所有\(\gcd(l...r)\)的约数\(d\)拿出来,建立一新树\(T'\),把边权为\(d\)的倍数的边插入\(T'\),然后统计每个连通块大小的二次方和。
由于最多会插入\(2^d\)条边,所以一次询问\(O(n2^d)\)。
有修改的情况显然可以维护\(n2^d\)个LCT,然后在修改边权后在LCT上link,cut\(2^d\)次。
然而问题并没有要求强制在线。
这种有连通块的题,显然考虑并查集维护。
考虑可撤销并查集。
有一些边没有被修改过,显然先插入进去。
注意到\(Q\)很小。
每次修改时提取出在其他询问中被修改的边,插入它在当前位置的值,然后把当前位置的边插入到数据结构中。
最后再撤销。
最终时间复杂度\(n2^d+2^d*Q^2*log_2n\)

上一篇:CF331E2 Deja Vu 图论


下一篇:CF331E2 Deja Vu