• 区间反转问题


    区间反转问题

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


    例题 洛谷 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,所以直接把每个节点的左右儿子交换就可以。

  • 相关阅读:
    form表单的应用
    HTML列表及表格的基本应用
    Linux上安装Jdk
    docker+jenkins自动发布步骤及命令
    redis集群部署实战
    mySQL中连接字符串
    mysql触发器
    sql 设置数字长度 不足时补0
    微服务架构特性
    SQLServer2008 去除换行符
  • 原文地址:https://www.cnblogs.com/fusiwei/p/13410154.html
Copyright © 2020-2023  润新知