zoukankan      html  css  js  c++  java
  • Splay和LCT的复杂度分析

    (Splay)的复杂度分析

    不论插入,删除还是访问,我们可以发现它们的复杂度都和(splay)操作的复杂度同阶,只是一点常数的区别

    我们不妨假设有(n)个点的(splay),进行了(m)(splay)操作


    采用势能分析

    我们记(w(x) = left lceil log_2 (size(x)) ight ceil),注意以(2)为底和上取整

    我们定义势能函数为(varphi = sum w(x))

    (记第(i)次操作操作完之后,势能为(varphi(i))

    只需要估计出(varphi(m) - varphi(m - 1) + varphi(m - 1) - varphi(m - 2) ... + varphi(1) - varphi(0) + varphi(0))的大小即可

    (即初始势能和每次的势能变化量的和)

    显然,(varphi(0) leqslant n log n)


    (splay)操作的具体定义为:

    如果父节点是根,那么旋转一次

    如果父节点和爷节点所处子树方向一致,那么先旋转父亲再旋转自己

    否则,旋转两次自己

    实际上可以归结于(zig)(zag)(zig-zig)(zag-zag)(zig-zag)(zag-zig)操作

    由于(zig)(zag)是对称的操作

    因此,只需要对(zig)(zig-zig)(zig-zag)操作分析复杂度即可


    (zig)操作

    势能的变化量为(1 + w'(x) + w'(fa) - w(x) - w(fa) leq 1 + w'(fa) - w(x) leq 1 + w'(x) - w(x))


    (zig-zig)操作

    势能变化量为(1 + w'(x) + w'(fa) + w'(g) - w(x) - w(fa) - w(g))(缩小了常数的影响,但不能无视)

    (leq 1 + w'(fa) + w'(g) - w(x) - w(fa) leq 1 + w'(x) + w'(g) - 2w(x))

    这是神仙复杂度证明中非常神奇的地方,通过一些有趣的性质,让常数项的代价合并到了势能的变化中

    我们不妨设(a = w'(g), b = w(x)),那么注意到(w'(x) = a + b + 1)

    由于$2w'(x) - w'(g) - w(x) = left lceil log_2 (a + b + 1) ight ceil - left lceil log_2 a ight ceil + left lceil log_2 a + b + 1 ight ceil - left lceil log_2 b ight ceil $

    注意到(a, b)在上式中是对称的,不妨设(a geq b)

    (geq left lceil log_2 (a + b + 1) ight ceil - left lceil log_2 b ight ceil geq left lceil log_2 (2b + 1) ight ceil - left lceil log_2 b ight ceil geq left lceil log_2 b ight ceil + 1 - left lceil log_2 b ight ceil geq 1)

    因此有(1 leq 2w'(x) - w'(g) - w(x)),我们将(1 + w'(x) + w'(g) - 2w(x))中的(1)放缩,可以得到

    (leq 3(w'(x) - w(x)))


    (zig-zag)操作

    势能变化量为(1 + w'(x) + w'(fa) + w'(g) - w(x) - w(fa) - w(g) leq 1 + w'(fa) + w'(g) - w(x) - w(fa) leq 1 + w'(g) + w'(fa) - 2w(x))

    由上文的结论,我们知道这里可以把(1)放缩成(1 leq 2w'(x) - w'(g) - w'(fa))

    因此(leq 2(w'(x) - w(x)))


    把以上三种操作的势能全部放缩为(leq 3(w'(x) - w(x)))

    不妨假设(splay)一次,依次访问了点(x_1, x_2 ... x_n),最后(x_1)会成为新的根

    那么,最后的势能实际上是(3(w'(x_1) - w(x_1) + w''(x_1) - w'(x_1) + .... + w(n) - w^{'''.....}(x_1)) + 1 = 3 * (w(n) - w(x_1)) + 1leq log_2 n)

    因此,(varphi(m) - varphi(m - 1) + varphi(m - 1) - varphi(m - 2) ... + varphi(1) - varphi(0) + varphi(0) = n log n + m log n)

    (n)个点的(splay),做(m)(splay)操作,复杂度为(O(n log n + m log n))


    (LCT)的复杂度分析

    不咕了....

    (LCT)的所有操作可以看做只有(access)操作,其他都是常数

    那么(access)操作一共有两部分

    • (splay)中走的复杂度

    • 访问虚边的复杂度


    首先是在(splay)中走的复杂度

    定义(w(x) = left lceil log_2 (size(x)) ight ceil)(size(x))(x)的所有虚边和实边的子树大小的和

    我们定义势能函数为(varphi = sum w(x))

    不妨设它依次访问了(x_1, x_2 ..., x_p)

    那么,类似上文(splay)的复杂度分析,我们可以得到总的一次势能变化量为(-w(x_1) +w(x_2) - w(x_2) + w(x_3) ... +w(x_p) + 1leq w(x_p) + 1 = O(log n))

    这也就是(splay)(finger-search)的性质

    初始势能为(n log n),因此这一部分的复杂度为(O(nlog n + m log n))


    访问虚边的复杂度

    我们定义势能函数(phi),为所有重虚边(儿子的子树大小大于等于自己的二分之一的虚边)的数量

    那么,每次访问至多走(log)条轻虚边,也就至多带来(log)条重虚边,也就是以(O(log))的代价增加(log)的势能

    而每次访问一条重虚边就需要付出(O(1))的代价来减小(1)的势能,并且访问完重虚边之后,不会有新的重虚边产生

    因此,最终的复杂度是初始势能和势能变化量(实际操作的代价和势能变化量相同)的和,也就是(O(n + m log n))


    因此,(LCT)的复杂度为(O(n log n + m log n))

  • 相关阅读:
    anaconda安装TensorFlow
    复习NLP-实战(三)
    复习NLP-实战(二)
    复习NLP-实战(一)
    python爬虫实战
    WebSocket实战(一)
    不上传图片直接本地预览
    oracle导出
    使用正则表达式验证学习成绩分数
    限制文本框,文本域输入的字符数量
  • 原文地址:https://www.cnblogs.com/reverymoon/p/10086216.html
Copyright © 2011-2022 走看看