ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

洛谷 P6668 - [清华集训2016] 连通子树(虚树+点分治)

2022-08-10 20:31:05  阅读:161  来源: 互联网

标签:连通 洛谷 log 包含 复杂度 P6668 虚树 DP


洛谷题面传送门

一道思维难度为 \(<\epsilon\) 的题。

首先先考虑单组询问的情况。有个究极暴力的做法,\(dp_{i,x,y,z}\) 表示 \(i\) 子树内三种颜色个数分别为 \(x,y,z\) 的连通块个数,转移相当于合并两个连通块,只能 \(O((na+1)^2(nb+1)^2(nc+1)^2)\) 地进行,因此单组询问复杂度 \(n(na+1)^2(nb+1)^2(nc+1)^2\),太逊了。

考虑优化这个暴力,一个切入点是上面的 DP 中合并复杂度很大,而如果我们假定根节点选择了,我们就可以采用【DFS 一个节点时,将父亲的 DP 值传给儿子,回溯时将儿子的 DP 值加到父亲上】的套路,这样就只涉及插入一个点,可以 \(O(1)\) 转移。而这样的 DP 一般只能与点分治相结合,具体方法就是点分治一个连通块时,考虑求出分治重心必选的方案数,这部分就套用上面的做法即可,时间复杂度 \(n\log n(na+1)(nb+1)(nc+1)\),但是有多组询问,同样不行。

到这里我们还没有用到每种颜色出现次数 \(\le 5\) 的性质。考虑如何应用之,另一个粗暴的想法是容斥,具体来说你先强制一些 \(a,b,c\) 必须选,然后二项式反演把它容斥掉,怎样求包含一个点集的连通块个数呢?首先建出这些点集的虚树,然后预处理出 \(dp_i\) 表示由 \(i\) 子树内组成的包含 \(i\) 的连通块个数,\(dpout_i\) 表示由 \(i\) 子树外的点组成的包含 \(fa_i\) 的连通块个数。那么这个方案数就直接将虚树周围的 \(dp_i+1\) 或者 \(dpout_i+1\) 乘起来即可。这样单组询问时间复杂度大概是 \(32^3·15·\log n\),还是不行。

考虑将二者结合在一起,建出三种颜色的 \(5\) 个点共 \(15\) 个点的虚树,然后在虚树上点分治即可。在建虚树的时候,我们要对于一条链 \(x,y\),求出有多少个 \(x\to y\) 的点及其子树内的点组成的连通块包含 \(x\) 不包含 \(y\),或者包含 \(y\) 不包含 \(x\),或者既包含 \(x\) 又包含 \(y\),这部分可以线段树/倍增预处理出来。时间复杂度 \(15(n+q)\log n+\sum abc·\log\sum abc\)。

然而看看就不想写(

标签:连通,洛谷,log,包含,复杂度,P6668,虚树,DP
来源: https://www.cnblogs.com/ET2006/p/luogu-P6668.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有