zoukankan      html  css  js  c++  java
  • 区间反转问题

    区间反转问题

    本篇随笔浅谈一下算法竞赛中的区间反转问题。


    例题 洛谷 P3391 【模板】文艺平衡树

    题目传送门

    题目描述

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列。

    其中需要提供以下操作:翻转一个区间,例如原有序序列是 5 4 3 2 15 4 3 2 1,翻转区间是 [2,4][2,4] 的话,结果是 5 2 3 4 15 2 3 4 1。

    输入格式

    第一行两个正整数 n,mn,m,表示序列长度与操作个数。序列中第 ii 项初始为 ii
    接下来 mm 行,每行两个正整数 l,rl,r,表示翻转的区间。

    输出格式

    输出一行 nn 个正整数,表示原始序列经过 mm 次变换后的结果。

    说明/提示

    【数据范围】
    对于 100%100% 的数据,1 le n, m leq 1000001≤n,m≤100000,1 le l le r le n1≤lrn


    关于区间反转

    对于反转一段区间的操作,我们好像怎么搞都是(O(N))的。

    然而对于这道题来讲,(O(N))算法肯定是过不去的。

    想要用更优秀的复杂度来做,怎么办呢?

    用平衡树来升级,而且必须用Splay。

    复杂度达到了均摊(O(log N))(证明别找我)。

    这就已经很优秀了。

    那么为什么平衡树的Splay算法能够用均摊(O(log N))的复杂度来实现区间反转呢?

    现在我们用节点编号来建一棵BST。那么根据BST的性质,对于一个针对区间([L,R])的反转操作,我们肯定需要把这个区间变到一个可以方便操作的位置。

    那么我们考虑把节点(L-1)用旋转splay到根节点,把节点(R+1)用旋转splay到根节点的右儿子,根据BST性质,因为我们是使用节点编号建的BST,那么我们就发现:右儿子的左子树就是我们需要操作的区间。这个区间已经被唯一确定下来了。

    然后因为我们是用节点编号建的BST,所以直接把每个节点的左右儿子交换就可以。

  • 相关阅读:
    python学习之路01
    面向对象(2)__继承多态1
    面向对象(1)____私有公有 访问限制
    property
    yield理解
    列表推导式
    Django序列化1_基本的序列化和反序列化
    一些滑动操作
    装饰器
    django模板
  • 原文地址:https://www.cnblogs.com/fusiwei/p/13410154.html
Copyright © 2011-2022 走看看