zoukankan      html  css  js  c++  java
  • 数树搞笑解法

    此处纯属搞笑,想学习正常解法的请欣赏其他题解。

    这里是子任务2的另一种解法,从(O(n^{2}))(dp)讲起,提出一个用重链剖分优化(dp),复杂度上界是(O(nlog_{2}^{4}n))的算法。

    ps:复杂度是我算出来的,不保证这个复杂度是这个算法的下界。

    前置芝士:

    1.(Sigma()轻儿子子树大小())=(nlog_2n)

    证明:我们对于每一个轻儿子,标记其子树内的所有点。那么,每一次标记就正好标记了子树大小次,我们要求的式子就转化为,对所有轻儿子标记之后,树上标记个数之和。我们考虑一个点在什么情况下会被标记一次:当且仅当它的一个祖先是轻儿子。我们又有一个众所周知的定理:在重剖下,一个点到根的路径上最多有(log_2n)条重链,(log_2n)条轻链,所以,一个点只有(log_2n)个祖先是轻儿子,一个点至多只会被标记(log_2n)次,故树上的标记个数之和的上界是(nlog_2n),证毕。

    2.求m个多项式的卷积

    我们可以两两相乘,然后多项式的个数少了一半,总长度不变,这样一直做下去,每一个多项式就被乘了(log_2m)次,一个多项式对复杂度的贡献就是(len*log_2m)

    (f_{i,j})表示以i节点为根的子树,i所在的连通块的大小为j的子树贡献之和。设x节点的f数组为(F(x)),再令(g_{i})表示i为孤立点时i子树内的贡献之和。

    那么我们有:
    (F_{i}(x)=x*prod_{jsubseteq son(i)}(F_{j}(x)+k*F_{j}^{'}(1)))

    想法0:

    我们知道(O(n^2))的dp实质是一个背包,所以我们可以用(FFT)优化背包,然而复杂度仍然可以被卡到(O(n^2))甚至更高。

    想法1:

    我们发现这个(dp)的下标是基于子树大小的,于是考虑重剖优化。
    对于重儿子,(O(1))继承其背包,对于轻儿子,用(FFT)优化背包,最后轻儿子和重儿子的结果卷起来。
    然而并没有什么区别,因为(FFT)的复杂度是和被卷的两个式子的长度有关的,于是复杂度中出现了重儿子的子树大小,这就使得树剖的优越性没有发挥出来。

    想法2:

    现在我们试图避免复杂度中出现关于重儿子子树大小的东西,然而,如果我们在一个点结束时把轻儿子的结果和重儿子卷起来的话,复杂度就一定会和重儿子有关,那么,我们就很自然的有了一个想法:能不能在最后不卷?

    如果我们不卷的话,就要拿数组来存它,因为(Sigma()轻儿子子树大小())(nlog_2n)的,所以空间是(nlog_2n)的,不用担心。而当我们需要调用它的时候我们再把它和它子树中所有的轻儿子的背包卷起来。

    具体实现:
    对于重儿子,(O(1))继承其背包,对于轻儿子,全部卷到一起之后,就放在那里不管,直接给它们分配一个新的内存。
    卷轻儿子的时候,先把这个轻儿子的背包生成函数卷出来,因为一个轻儿子也是一条重链的top,直接把它的重链上的全部轻儿子全部卷起来,再和当前节点的其他轻儿子卷。

    复杂度的证明:
    我们考虑一个轻儿子被卷了多少次,显然当且仅当它的一个祖先是轻儿子时它被卷一次,故至多被用来求解(log_{2}n)次,每一次被用来求解,都是与当前要求解的这个祖先的重链上所有的轻儿子卷,多项式的数量是(Theta(n))级别的,所以用前置知识中的多个多项式卷积的方法的话一个轻儿子的多项式在一次求解中会被卷(log_{2}n)次,一次卷积对复杂度的贡献是(siz*log_{2}(siz)),故总复杂度是:
    (Sigma siz*log_{2}siz*log_{2}^{2}n=log_{2}^{2}nSigma siz*log_{2}sizleq log_{2}^{2}nSigma siz*log_{2}n=nlog_{2}^{4}n)

    说着也不长,打起来估计是极其难受。

    当然如果你是一个打FFT优化背包+下标偏移+动态分配内存就像吃饭喝水一样简单的人的话,一定可以轻松的写出这个算法的。

    本人没有实现这个算法,纯属口胡,如果这个算法锅了麻烦各位神仙指出,谢谢。

  • 相关阅读:
    vi 或 vim 常用命令(简单够用了)
    linux 常用命令
    ssh连接远程linux服务器
    tomcat优化系列:修改运行内存
    html学习笔记二
    html学习笔记一
    我的subLime的快捷键
    CentOS tomcat 安装与自启动
    CentOS 安装jdk-8u111-linux-x64.tar.gz方法
    CentOS 6 默认启动进入 图形或命令窗口
  • 原文地址:https://www.cnblogs.com/thedreammaker/p/13160328.html
Copyright © 2011-2022 走看看