动态的最大子段和

就是splay啊,说一下GSS1吧,维护四个值,一个是这个区间和(下面说sum),

一个是从左边开始的最大和(下面说ls)和右边开始的最大和(下面说rs),

还有一个就是最大区间和(mx),那么

$$ls = max(leftson -> ls, leftson -> sum + rightson -> ls)$$

$$rs = ......$$

$$sum = leftson -> sum + rightson -> sum$$

$$mx = max(leftson -> sum, max(rightson -> sum, leftson ->
rs + rightson -> ls ))$$

就是这样,然后再伸展树里各种特判,一个也不可以少考虑

然后就是这道题至少选一个数啊

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
struct Node{
    Node *ch[2];
    int s, v, ls, rs, sum, ans, k, 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(){
        int yy, yt;

        s = 1;
        if(ch[0]) s += ch[0] -> s;
        if(ch[1]) s += ch[1] -> s;

        sum = v;
        if(ch[0]) sum += ch[0] -> sum;
        if(ch[1]) sum += ch[1] -> sum;

        ls = -214748364;
        if(ch[0]) ls = max(ls, ch[0] -> ls);
        yy = v;
        if(ch[0]) yy += ch[0] -> sum;
        yt = 0;
        if(ch[1]) yt = ch[1] -> ls;
        ls = max(ls, max(yy, yy + yt));

        rs = -214748364;
        if(ch[1]) rs = max(rs, ch[1] -> rs);
        yy = v;
        if(ch[1]) yy += ch[1] -> sum;
        yt = 0;
        if(ch[0]) yt = ch[0] -> rs;
        rs = max(rs, max(yy, yy + yt));

        ans = v;
        if(ch[0]) ans = max(ans, ch[0] -> ans);
        if(ch[1]) ans = max(ans, ch[1] -> ans);
        yy = 0;
        if(ch[0]) yy = ch[0] -> rs;
        yt = 0;
        if(ch[1]) yt = ch[1] -> ls;
        ans = max(ans, max(yy + yt + v, max(yy + v, yt + v)));
        return;
    }

    inline void pushdown(){
        if(f == 1){
            if(ch[0]){
                swap(ch[0] -> ch[0], ch[0] -> ch[1]);
                ch[0] -> f ^= 1;
                swap(ch[0] -> ls, ch[0] -> rs);
            }

            if(ch[1]){
                swap(ch[1] -> ch[0], ch[1] -> ch[1]);
                ch[1] -> f ^= 1;
                swap(ch[1] -> ls, ch[1] -> rs);
            }

            f = 0;
        }

        if(k != -214748364){
            if(ch[0]){
                ch[0] -> f = 0;
                ch[0] -> v = k;
                ch[0] -> sum = ch[0] -> s * k;
                if(k > 0){
                    ch[0] -> ls = ch[0] -> rs = ch[0] -> ans = ch[0] -> s * k;
                }
                else{
                    ch[0] -> ls = ch[0] -> rs = ch[0] -> ans = k;
                }
                ch[0] -> k = k;
            }

            if(ch[1]){
                ch[1] -> f = 0;
                ch[1] -> v = k;
                ch[1] -> sum = ch[1] -> s * k;
                if(k > 0){
                    ch[1] -> ls = ch[1] -> rs = ch[1] -> ans = ch[1] -> s * k;
                }
                else{
                    ch[1] -> ls = ch[1] -> rs = ch[1] -> ans = k;
                }
                ch[1] -> k = k;
            }   

            k = -214748364;
        }
    }

};
struct splay_tree{
    int a[500000];
    int size;
    Node* p;

    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 = k;
        return;
    }

    inline void splay(Node* &o, int k){
        o -> 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];
            w -> pushdown();
            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);
        }
        o -> maintain();
        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();
        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();
        return;
    }

    inline void insert(Node* &o, int l, int r){
        if(r < l) return;
        int mid = (l + r) / 2;
        o = new Node();
        o -> ch[0] = o -> ch[1] = NULL;
        o -> v = a[mid];
        o -> f = 0;
        o -> k = -214748364;
        if(l != r){
            insert(o -> ch[0], l, mid - 1);
            insert(o -> ch[1], mid + 1, r);
        }
        o -> maintain();
        return;
    }

    inline void add(int pos, int tot){
        Node *left, *mid, *right;
        split(p, pos, left, right);
        insert(mid, 1, tot);
        p = merge(left, merge(mid, right));
        return;
    }

    inline void delete_splay_tree(Node* &o){
        if(o -> ch[0] != NULL) delete_splay_tree(o -> ch[0]);
        if(o -> ch[1] != NULL) delete_splay_tree(o -> ch[1]);
        delete o;
        return;
    }

    inline void Delete(int pos, int l){
        Node *left, *mid, *right;
        split(p, pos - 1, left, mid);
        split(mid, l, mid, right);
        delete_splay_tree(mid);
        left = merge(left, right);
        p = left;
        return;
    }

    inline void flip(Node* &o, int l, int r){
        Node *left, *mid, *right;
        split(p, l - 1, left, mid);
        split(mid, r, mid, right);
        swap(mid -> ch[0], mid -> ch[1]);
        mid -> f ^= 1;
        swap(mid -> ls, mid -> rs);
        p = merge(left, merge(mid, right));
        return;
    }

    inline void make_same(Node* &o, int l, int r, int c){
        Node *left, *mid, *right;
        split(p, l - 1, left, mid);
        split(mid, r, mid, right);
        mid -> v = c;
        mid -> sum = mid -> s * c;
        if(c > 0){
            mid -> ls = mid -> rs = mid -> ans = mid -> s * c;
        }
        else{
            mid -> ls = mid -> rs = mid -> ans = c;
        }
        mid -> k = c;
        p = merge(left, merge(mid, right));
        return;
    }

    inline int query_sum(Node* &o, int l, int r){
        if(r == 0) return 0;
        Node *left, *mid, *right;
        split(p, l - 1, left, mid);
        split(mid, r, mid, right);
        int ret = mid -> sum;
        p = merge(left, merge(mid, right));
        return ret;
    }

    inline int query_boss(Node* &o){
        return o -> ans;
    }

} wt;
int main(){
    int n, m;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i ++){
        scanf("%d", &wt.a[i]);
    }
    wt.insert(wt.p, 1, n);
    char str[100];
    int pos, tot, c;
    for(int i = 1; i <= m; i ++){
        scanf("%s", str);
        if(str[0] == 'I'){
            scanf("%d%d", &pos, &tot);
            for(int j = 1; j <= tot; j ++) scanf("%d", &wt.a[j]);
            if(tot == 0) continue;
            wt.add(pos, tot);
        }
        else if(str[0] == 'D'){
            scanf("%d%d", &pos, &tot);
            if(tot == 0) continue;
            wt.Delete(pos, tot);
        }
        else if(str[2] == 'K'){
            scanf("%d%d%d", &pos, &tot, &c);
            if(tot == 0) continue;
            wt.make_same(wt.p, pos, tot, c);
        }
        else if(str[0] == 'R'){
            scanf("%d%d", &pos, &tot);
            if(tot == 0) continue;
            wt.flip(wt.p, pos, tot);
        }
        else if(str[0] == 'G'){
            scanf("%d%d", &pos, &tot);
            printf("%d\n", wt.query_sum(wt.p, pos, tot));
        }
        else{
            int ret = wt.query_boss(wt.p);
            printf("%d\n", ret);
        }
        //printf("%d:%d\n", i, wt.p -> s);
    }
    return 0;
}

BZOJ1500——维修序列的更多相关文章

  1. [bzoj1269]文本编辑器editor [bzoj1500]维修数列

    1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2540 Solved: 923 [Submit ...

  2. BZOJ1500 维修数列

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=1500 [前言] 据说没打这题就相当于没打过Splay,这题简直就是让你内心崩溃的... 这 ...

  3. [bzoj1500 维修数列](NOI2005) (splay)

    真的是太弱了TAT...光是把代码码出来就花了3h..还调了快1h才弄完T_T 号称考你会不会splay(当然通过条件是1h内AC..吓傻)... 黄学长的题解:http://hzwer.com/28 ...

  4. bzoj 1500 维修序列

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

  5. 可持久化Treap(fhq Treap,非旋转式Treap)学习(未完待续)

    简介:     Treap,一种表现优异的BST 优势:     其较于AVL.红黑树实现简单,浅显易懂     较于Splay常数小,通常用于树套BST表现远远优于Splay     或许有人想说S ...

  6. 【splay模板】

    #include <iostream> #include <cstring> #include <algorithm> #include <cstdio> ...

  7. 关于oi

    2015-12-26 今天在机房,楼上的孩子发下来一个exe,善良无知的我打开了那个exe,然后电脑就关机了.萌萌的辅导老师看到之后就不再萌萌哒,他跑到五楼训斥了那群孩子们一顿(自行脑补).出于报复, ...

  8. 个人整理的数组splay板子,指针的写的太丑了就不放了。。

    splay的板子.. 由于被LCT榨干了..所以昨天去学了数组版的splay,现在整理一下板子.. 以BZOJ3224和3223为例题..暂时只有这些,序列的话等有时间把维修序列给弄上来!! BZOJ ...

  9. POJ3580 SuperMemo

    Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to pl ...

随机推荐

  1. FIFA halts 2026 bids amid scandal 国际足联在丑闻期间停止2026年足球世界杯申请

    FIFA halts 2026 bids amid scandal 国际足联在丑闻期间停止2026年足球世界杯申请 But official insists 2018 Cup will stay in ...

  2. js005-引用类型

    js005-引用类型 数据类型分为基本类型和引用类型:基本类型值如下:Undefined.Null.Bollean.Number.String 本章内容: 1.使用对象 2.创建并操作数组 3.理解基 ...

  3. WinForm------TextEdit控件去掉换行符

    //将换行转为空格 string str = this.DetailEdit.Text.Replace("\r\n"," ");

  4. SOCKADDR_IN

    在windows/linux下有下面结构: sockaddr结构 struct sockaddr { unsigned short sa_family;/*addressfamily,AF_xxx*/ ...

  5. C# LIST列表的使用

    1.  List的基础.常用方法: 声明: 1.List<T> mList = new List<T>(); T为列表中元素类型,现在以string类型作为例子 E.g.: L ...

  6. 《深入理解bootstrap》读书笔记:第二章 整体架构

    一.  整体架构   1. CSS-12栅格系统 把网页宽度均分为12等分(保留15位精度)--这是bootstrap的核心功能. 2.基础布局组件 包括排版.按钮.表格.布局.表单等等. 3.jQu ...

  7. C#----操作应用程序配置文件App.config

    对配置文件的一些疑问: 在应用程序的目录下,有两处值得注意的地方,一个是应用程序根目录下的App.config文件,和bin\debug\name.exe.config 或者 bin\Release\ ...

  8. expect神器安装和使用

    安装: mdkir /data/tools cd /data/tools wget http://prdownloads.sourceforge.net/tcl/tcl8.5.19-src.tar.g ...

  9. thikphp创建共享数据config.php

    要求:前台,后台:只需要配置一个config.php 其他文件共享 默认配置是 Index/Conf/config.php Admin/Conf/config.php 代码: return array ...

  10. 2015 前端[JS]工程师必知必会

    2015 前端[JS]工程师必知必会 本文摘自:http://zhuanlan.zhihu.com/FrontendMagazine/20002850 ,因为好东东西暂时没看懂,所以暂时保留下来,供以 ...