给你一个数列,让你实现区间加上一个值,区间翻转,区间最大值

裸splay,懒标记一发即可

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
struct Node{
    Node *ch[2];
    int m, v, k, s, f;
    inline int cmp(int x){
        int o = 0;
        if(ch[0] != NULL){
            if(ch[0] -> s >= x) return 0;
            o += ch[0] -> s;
        }
        if(o + 1 == x) return -1;
        return 1;
    }
    inline void maintain(){
        s = 1;
        if(ch[0] != NULL) s += ch[0] -> s;
        if(ch[1] != NULL) s += ch[1] -> s;
        return;
    }
    inline void Back(){
        m = v;
        if(ch[0] != NULL) m = max(m, ch[0] -> m);
        if(ch[1] != NULL) m = max(m, ch[1] -> m);
        return;
    }
    inline void pushdown(){
        if(f == 1){
            if(ch[0] != NULL){
                ch[0] -> f ^= 1;
                swap(ch[0] -> ch[0], ch[0] -> ch[1]);
            }
            if(ch[1] != NULL){
                ch[1] -> f ^= 1;
                swap(ch[1] -> ch[0], ch[1] -> ch[1]);
            }
            f = 0;
        }
        if(ch[0] != NULL){
            ch[0] -> k += k;
            ch[0] -> m += k;
            ch[0] -> v += k;
        }
        if(ch[1] != NULL){
            ch[1] -> k += k;
            ch[1] -> m += k;
            ch[1] -> v += k;
        }
        k = 0;
        return;
    }
};
struct splay_tree{
    Node ft[1000000];
    int size;
    Node *p;
    int x, y;
    inline void init(){
        size = 0;
        return;
    }
    inline void rotate(Node* &o, int d){
        Node *k = o -> ch[d ^ 1];
        k -> pushdown(); //注意这里
        o -> ch[d ^ 1] = k -> ch[d];
        k -> ch[d] = o;
        o -> maintain();
        k -> maintain();
        o -> Back();
        k -> Back();
        o = k;
        return;
    }
    inline void splay(Node* &o, int k){
        o -> pushdown();
        if(o -> ch[0] != NULL) o -> ch[0] -> pushdown();
        if(o -> ch[1] != NULL) o -> ch[1] -> pushdown();
        int d = o -> cmp(k);
        if(d == 1 && o -> ch[0] != NULL) k = k - o -> ch[0] -> s - 1;
        else if(d == 1) k --;
        if(d != -1){
            Node* w = o -> ch[d];
            int d2 = w -> cmp(k);
            int k2 = k;
            if(d2 != 0){
                k2 --;
                if(w -> ch[0] != NULL) k2 -= w -> ch[0] -> s;
            }
            if(d2 != -1){
                splay(w -> ch[d2], k2);
                if(d == d2) rotate(o, d ^ 1);
                else rotate(o -> ch[d], d);
            }
            rotate(o, d ^ 1);
        }
        if(o -> ch[0] != NULL) o -> ch[0] -> pushdown();
        if(o -> ch[1] != NULL) o -> ch[1] -> pushdown();
        o -> Back();
        return;
    }
    inline Node* merge(Node *left, Node *right){
        if(left == NULL) return right;
        if(right == NULL) return left;
        splay(left, left -> s);
        left -> ch[1] = right;
        left -> maintain();
        left -> Back();
        return left;
    }
    inline void split(Node* &o, int k, Node* &left, Node* &right){
        if(k == 0){
            left = NULL;
            right = o;
            return;
        }
        splay(o, k);
        left = o;
        right = o -> ch[1];
        left -> ch[1] = NULL;
        left -> maintain();
        left -> Back();
        return;
    }
    inline void insert(Node* &o, int l, int r){
        if(r < l) return;
        int mid = (l + r) / 2;
        o = &ft[size]; size ++;
        o -> ch[0] = o -> ch[1] = NULL;
        o -> v = o -> m = o -> f = o -> k = 0;
        if(l != r){
            insert(o -> ch[0], l, mid - 1);
            insert(o -> ch[1], mid + 1, r);
        }
        o -> maintain();
        return;
    }
    inline void add1(Node* &o, int l, int r, int t){
        if(r < l) return;
        o -> pushdown();
        if(y < l || r < x) return;
        if(x <= l && r <= y){
            o -> m += t;
            o -> v += t;
            o -> k += t;
            return;
        }
        int mid = l;
        if(o -> ch[0] != NULL) mid += o -> ch[0] -> s;
        if(x <= mid && mid <= y) o -> v += t;
        if(o -> ch[0] != NULL) add1(o -> ch[0], l, mid - 1, t);
        if(o -> ch[1] != NULL) add1(o -> ch[1], mid + 1, r, t);
        o -> Back();
        return;
    }
    inline void add2(Node* &o, int l, int r){
        Node *left, *mid, *right;
        split(p, l - 1, left, mid);
        split(mid, r - l + 1, mid, right);
        swap(mid -> ch[0], mid -> ch[1]);
        mid -> f ^= 1;//注意这里
        p = merge(left, merge(mid, right));
        return;
    }
    inline int query(Node* &o, int l, int r){
        if(r < l) return -2147483640;
        o -> pushdown();
        if(y < l || r < x) return -214743640;
        if(x <= l && r <= y) return o -> m;
        int mid = l;
        if(o -> ch[0] != NULL) mid += o -> ch[0] -> s;
        int ret = -2147483640;
        if(x <= mid && mid <= y) ret = o -> v;
        if(o -> ch[0] != NULL) ret = max(ret, query(o -> ch[0], l, mid - 1));
        if(o -> ch[1] != NULL) ret = max(ret, query(o -> ch[1], mid + 1, r));
        o -> Back();
        return ret;
    }
} wt;
int main(){
    /*freopen("seq1.in", "r", stdin);
    freopen("seq.out", "w", stdout);*/
    int n, m;
    scanf("%d%d", &n, &m);
    wt.insert(wt.p, 1, n);
    for(int i = 1; i <= m; i ++){
        int o;
        int a, b, c;
        scanf("%d", &o);
        if(o == 1){
            scanf("%d%d%d", &a, &b, &c);
            wt.x = a; wt.y = b;
            wt.add1(wt.p, 1, n, c);
        }
        else if(o == 2){
            scanf("%d%d", &a, &b);
            wt.add2(wt.p, a, b);
        }
        else{
            scanf("%d%d", &a, &b);
            wt.x = a; wt.y = b;
            printf("%d\n", wt.query(wt.p, 1, n));
        }
    }
    return 0;
}

BZOJ1251——序列终结者的更多相关文章

  1. [BZOJ1251]序列终结者

    [BZOJ1251]序列终结者 试题描述 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题 ...

  2. [bzoj1251]序列终结者_splay

    序列终结者 bzoj-1251 题目大意:给定一个长度为n的正整数序列,支持区间加,区间反转,查询区间最大值.所有元素开始都是0. 注释:$1\le n\le 5\cdot 10^4$,操作个数不多于 ...

  3. bzoj1251 序列终结者(Splay Tree+懒惰标记)

    Description 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这 ...

  4. BZOJ1251序列终结者——非旋转treap

    题目描述 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技 ...

  5. [bzoj1251]序列终结者——splay

    题目大意 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技 ...

  6. BZOJ1251 序列终结者(Splay平衡树)(占位)

    网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量…… ...

  7. bzoj1251 序列终结者(splay)

    人生第一发splay,写得巨丑,最后忘记了push_down以后要将子节点maintain 9k代码不忍直视 #define NDEBUG #include<cstdio> #includ ...

  8. 题解【bzoj1251 序列终结者】

    Description 维护三个操作:区间加,区间翻转,区间求最大值.\(n \leq 50000\) Solution fhqtreap大法好! 模板题(我是不会告诉你这篇题解是用来存个代码的 Co ...

  9. bzoj1251: 序列终结者 fhqtreap写法

    fhqtreap的速度果然很快 花了时间学了下指针写法 没有旋转 只有分裂以及合并操作 其实还是蛮好写的 #include<cstdio> #include<cstring> ...

随机推荐

  1. maven的环境搭建

    maven环境快速搭建 最近,开发中要用到maven,所以对maven进行了简单的学习. .关于maven是什么东东,请参考其它文章. ----------------准备工作------------ ...

  2. 使用ultraiso制作启动盘

    1.以管理员方式运行Ultralso 2.点击菜单栏里的“启动”菜单下的“写入硬盘映像”命令,打开“写入硬盘映像”对话框. “硬盘驱动器”里就是选择你要刻录的U盘,这里演示用的是一张数码相机的内存卡. ...

  3. case when then else end

    1.根据数据库表中特定的值进行排序显示 select * from tablename where order by case when columname='' then 1 wnen column ...

  4. JavaScript学习笔记——节点

    javascript-节点属性详解 根据 DOM,HTML 文档中的每个成分都是一个节点. DOM 是这样规定的: 整个文档是一个文档节点 每个 HTML 标签是一个元素节点 包含在 HTML 元素中 ...

  5. JAVA基础知识(转)

    本文就java基础部分容易混淆的一些知识点进行了一下总结.因为Java本身知识点非常多,不可能在很短的篇幅就能叙述完,而且就某一个点来讲,如欲仔细去探究,也能阐述的非常多.这里不做全面仔细的论述,仅做 ...

  6. ELMAH日志组件数据库脚本

    CREATE TABLE dbo.ELMAH_Error ( ErrorId UNIQUEIDENTIFIER NOT NULL, Application NVARCHAR() COLLATE SQL ...

  7. centos 7.0最小化安装 查看yum 所有安装的软件包~

    使用命令 yum list installed [root@localhost ~]# yum list installed 已加载插件:fastestmirror base | 3.6 kB 00: ...

  8. 巧用array_map()和array_reduce()替代foreach循环

    1.array_reduce( $arr , callable $callback ) 使用回调函数迭代地将数组简化为单一的值. 其中$arr 为输入数组,$callback($result , $v ...

  9. gradle 的sourceCompatibility 与 targetCompatibility 区别

    sourceCompatibility:指定编译编译.java文件的jdk版本 targetCompatibility:确保class文件与targetCompatibility指定版本,或者更新的j ...

  10. 扩展struts2的结果集StrutsResultSupport 自定义Result处理JSON

    以前在采用Struts2开发的项目中,对JSON的处理一直都在Action里处理的,在Action中直接Response,最近研读了一下Struts2的源码,发现了一个更加优雅的解决办法,自己定义一个 ...