[NOI2005] 维护数列(平衡树)

题目

描述

请写一个程序,要求维护一个数列,支持以下6种操作:(请注意,格式栏中的下划线‘ _ ’表示实际输入文件中的空格)

  1. 插入 INSERT_posi_tot_c1_c2_…_ctot 在当前数列的第posi个数字后插入tot个数字:c1, c2, …, ctot;若在数列首插入,则posi为0
  2. 删除 DELETE_posi_tot 从当前数列的第posi个数字开始连续删除tot个数字
  3. 修改 MAKE-SAME_posi_tot_c 将当前数列的第posi个数字开始的连续tot个数字统一修改为c
  4. 翻转 REVERSE_posi_tot 取出从当前数列的第posi个数字开始的tot个数字,翻转后放入原来的位置
  5. 求和 GET-SUM_posi_tot 计算从当前数列开始的第posi个数字开始的tot个数字的和并输出
  6. 求和最大的子列 MAX-SUM 求出当前数列中和最大的一段子列,并输出最大和

输入格式

输入文件的第 1 行包含两个数 N 和 M,N 表示初始时数列中数的个数,M 表示要进行的操作数目。 第 2 行包含 N 个数字,描述初始时的数列。 以下 M 行,每行一条命令,格式参见问题描述中的表格

输出格式

对于输入数据中的 GET-SUM 和 MAX-SUM 操作,向输出文件依次打印结 果,每个答案(数字)占一行。

输入样例

9 8 2 -6 3 5 1 -5 -3 6 3 
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM

输出样例

-1
10
1
10

说明

你可以认为在任何时刻,数列中至少有 1 个数。
输入数据一定是正确的,即指定位置的数在数列中一定存在。
50%的数据中,任何时刻数列中最多含有 30 000 个数;
100%的数据中,任何时刻数列中最多含有 500 000 个数。
100%的数据中,任何时刻数列中任何一个数字均在[-1 000, 1 000]内。
100%的数据中,M ≤20 000,插入的数字总数不超过 4 000 000 。


解题思路

平衡树… Splay

基本知识

在Splay中进行区间修改时,假设要改的区间是 [l,r] [ l , r ] ,我们利用Splay的伸展操作将 l1 l − 1 旋转至根,将 r+1 r + 1 旋转至根的右儿子,那么要操作的区间 [l,r] [ l , r ] 就在根的右儿子的左儿子上了。
为了避免找不到 l1 l − 1 r+1 r + 1 的尴尬,可以事先在平衡树的首尾各插入一个保护节点,然后把每个对 [l,r] [ l , r ] 操作改成对 [l+1,r+1] [ l + 1 , r + 1 ] 的操作就行了,好写好调。

Splay结构体

struct Splay{
    int son[2], fa, size;// Basic info.
    int sum, mx, lmx, rmx, val;// Maintained info.
    int cov, rev;// tags
    Splay(){
        son[0] = son[1] = fa = size = 0;
        sum = lmx = rmx = 0, val = mx = -INF;
        cov = -INF, rev = 0;
    }
}tr[N];
  • 基本信息
  • 这道题要维护的信息
    • sum:以该节点为根的子树所包含的区间中所有值的和
    • mx, lmx, rmx:mx是区间中的最大子段和,联想线段树中区间最大子段和的维护,我们也需要lmx和rmx,即从左端点往右走的最大子段和从右端点往左走的最大子段。那么:
      tr[id].mx=max(max(tr[lson].m
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值