NOI2005维护数列

首先声明是codevs写法,bzoj限制64M必须动态分配内存,否则妥妥地MLE(0ms就T了)

  • 原题就不打了。
    巨型splay模板题,省选前两天突击splay就拿这道题练了练手。练了提取区间、区间插入、删除、求和,都是基础的。有一个细节需要注意一点:下传翻转标记时一定要先传到子树的子树并立即交换左右子树,否则在splay的过程中会使带标记的子树“还没按标记修改就拿来修改它的父亲了”。操作6“wfwbz”已有详细介绍,此处不再赘述。

  • Code:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 3000000, nil = 0, oo = 1000000000;
int fa[maxn], son[maxn][2], key[maxn], maxl[maxn], maxr[maxn], maxs[maxn], sum[maxn], s[maxn];
bool same[maxn], rev[maxn];
int n, m, root;
inline void read(int &a) {
    int f = 1;
    char ch = getchar();
    a = 0;
    while(ch < '0' || ch > '9') {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') {
        a = a*10 + ch - 48;
        ch = getchar();
    }
    a *= f;
}
inline void write(int a) {
    int top = 0;
    char ch[30];
    if(a < 0) { putchar('-'); a = -a; }
    do {
        ch[top++] = a%10 + 48;
        a /= 10;
    } while(a);
    while(top--) putchar(ch[top]);
    putchar('\n');
}
inline void update(int x) {
    s[x] = s[son[x][0]] + s[son[x][1]] + 1;
    sum[x] = sum[son[x][0]] + sum[son[x][1]] + key[x];
    maxs[x] = max(maxs[son[x][0]], maxs[son[x][1]]);
    maxs[x] = max(maxs[x], maxl[son[x][1]] + key[x] + maxr[son[x][0]]);
    maxl[x] = max(maxl[son[x][0]], sum[son[x][0]] + key[x] + maxl[son[x][1]]);
    maxr[x] = max(maxr[son[x][1]], sum[son[x][1]] + key[x] + maxr[son[x][0]]);
}
inline void rotate(int x, int w) {
    int y = fa[x];
    son[y][w^1] = son[x][w];
    if(son[x][w] != 0) fa[son[x][w]] = y;
    fa[x] = fa[y];
    if(fa[y] != nil)
        if(y == son[fa[y]][0]) son[fa[y]][0] = x;
        else son[fa[y]][1] = x;
    son[x][w] = y;
    fa[y] = x;
    update(y); update(x);
}
inline void splay(int x, int poi) {
    if(x == nil) return;
    while(fa[x] != poi) {
        if(fa[fa[x]] == poi)
            if(x == son[fa[x]][0]) rotate(x, 1);
            else rotate(x, 0);
        else
            if(fa[x] == son[fa[fa[x]]][0])
                if(x == son[fa[x]][0])
                { rotate(fa[x], 1); rotate(x, 1); }
                else
                { rotate(x, 0); rotate(x, 1); }
            else
                if(x == son[fa[x]][0])
                { rotate(x, 1); rotate(x, 0); }
                else
                { rotate(fa[x], 0); rotate(x, 0); }
    }
    if(poi == nil) root = x;
}
inline void pushdown(int x) {
    if(rev[x]) {
        rev[x] = false;
        rev[son[x][0]] ^= 1; rev[son[x][1]] ^= 1;
        swap(maxl[son[x][0]], maxr[son[x][0]]);
        swap(maxl[son[x][1]], maxr[son[x][1]]);
        swap(son[son[x][0]][0], son[son[x][0]][1]);
        swap(son[son[x][1]][0], son[son[x][1]][1]);
    }
    if(same[x]) {
        if(son[x][0] != nil) {
            key[son[x][0]] = key[x];
            sum[son[x][0]] = key[x]*s[son[x][0]];
            same[son[x][0]] = true;
            if(key[x] >= 0) maxl[son[x][0]] = maxr[son[x][0]] = maxs[son[x][0]] = sum[son[x][0]];
            else { maxl[son[x][0]] = maxr[son[x][0]] = 0; maxs[son[x][0]] = key[son[x][0]]; }
        }
        if(son[x][1] != nil) {
            key[son[x][1]] = key[x];
            sum[son[x][1]] = key[x]*s[son[x][1]];
            same[son[x][1]] = true;
            if(key[x] >= 0) maxl[son[x][1]] = maxr[son[x][1]] = maxs[son[x][1]] = sum[son[x][1]];
            else { maxl[son[x][1]] = maxr[son[x][1]] = 0; maxs[son[x][1]] = key[son[x][1]]; }
        }
        same[x] = false;
    }
}
void build(int l, int r, int fater, bool ch) {
    if(l > r) return;
    int rot = ((l + r) >> 1);
    son[fater][ch] = rot; fa[rot] = fater;
    build(l, rot-1, rot, 0); build(rot+1, r, rot, 1);
    update(rot);
}
inline int find(int x, int k) {
    pushdown(x);
    if(k == s[son[x][0]] + 1) return x;
    if(k <= s[son[x][0]]) return find(son[x][0], k);
    else return find(son[x][1], k - s[son[x][0]] - 1);
}
int pos, tot, c;
char cst[20];
void insert() {
    for(int i = n+1; i <= n+tot; ++i) read(key[i]);
    splay(find(root, pos+1), nil); splay(find(root, pos+2), root);
    build(n+1, n+tot, son[root][1], 0);
    n += tot;
    update(son[root][1]); update(root);
}
inline void dlete() {
    splay(find(root, pos), nil); splay(find(root, pos+tot+1), root);
    son[son[root][1]][0] = nil;
    update(son[root][1]); update(root);
}
inline void change() {
    splay(find(root, pos), nil); splay(find(root, pos+tot+1), root);
    int rot = son[son[root][1]][0];
    key[rot] = c; sum[rot] = c*s[rot]; same[rot] = true;
    if(c > 0) maxl[rot] = maxr[rot] = maxs[rot] = sum[rot];
    else { maxl[rot] = maxr[rot] = 0; maxs[rot] = key[rot]; }
    update(son[root][1]); update(root);
}
inline void rever() {
    splay(find(root, pos), nil); splay(find(root, pos+tot+1), root);
    int rot = son[son[root][1]][0];
    if(!same[root]) {
        rev[rot] ^= 1;
        swap(son[rot][0], son[rot][1]);
        swap(maxl[rot], maxr[rot]);
    }
    update(son[root][1]); update(root);
}
inline int querysum() {
    splay(find(root, pos), nil); splay(find(root, pos+tot+1), root);
    return sum[son[son[root][1]][0]];
}
inline int querylst() {
    return maxs[root];
}
int main() {
    read(n); read(m); n += 2;
    for(int i = 2; i < n; ++i) read(key[i]);
    key[1] = key[n] = maxs[nil] = -oo;
    build(1, n, 0, 0); root = ((n + 1) >> 1);
    for(int i = 1; i <= m; ++i) {
        scanf("%s", &cst);
        switch(cst[2]) {
            case 'S' :read(pos); read(tot); insert(); break;
            case 'L' :read(pos); read(tot); dlete(); break;
            case 'K' :read(pos); read(tot); read(c); change(); break;
            case 'V' :read(pos); read(tot); rever(); break;
            case 'T' :read(pos); read(tot); write(querysum()); break;
            case 'X' :write(querylst()); break;
            default :;
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值