BZOJ 1500 维修数列

Splay序列操作的大模板题

这个真的是噩梦。。调了整整一个晚上,可以说完全被榨干了orz。。
因为我的splay写的实在是太丑了,手动加的哨兵节点,开头忘记pushup了,找了一晚上才找到。。。
还有就是0节点的mx也要设置成-INF,否则会影响我门原树叶子结点的mx。。其他的就靠造化了。。

还要注意的是数组500000就够了,剩下的靠内存池维护,不然在BZOJ上会爆内存,但是他显示的是TLE。。不仅题目坑,这个评测也挺不友好的。。但是在洛谷还是可以过的

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define full(a, b) memset(a, b, sizeof a)
using namespace std;
typedef long long ll;
inline int lowbit(int x){ return x & (-x); }
inline int read(){
    int X = 0, w = 0; char ch = 0;
    while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
    while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
    return w ? -X : X;
}
inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }
inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
template<typename T>
inline T max(T x, T y, T z){ return max(max(x, y), z); }
template<typename T>
inline T min(T x, T y, T z){ return min(min(x, y), z); }
template<typename A, typename B, typename C>
inline A fpow(A x, B p, C lyd){
    A ans = 1;
    for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
    return ans;
}

const int N = 500005;
int ch[N][2], sum[N], mx[N], lx[N], rx[N], lazy[N], rev[N], val[N], fa[N], size[N], a[N];
int tot, n, m, root;
queue<int> q;
int newNode(int p, int v){
    if(!q.empty()){
        int ret = q.front(); q.pop();
        sum[ret] = v, mx[ret] = val[ret] = v;
        if(v >= 0) lx[ret] = rx[ret] = v;
        else lx[ret] = rx[ret] = 0;
        lazy[ret] = rev[ret] = ch[ret][0] = ch[ret][1] = 0;
        fa[ret] = p, size[ret] = 1;
        return ret;
    }
    else{
        sum[++tot] = v, mx[tot] = val[tot] = v;
        if(v >= 0) lx[tot] = rx[tot] = v;
        else lx[tot] = rx[tot] = 0;
        lazy[tot] = rev[tot] = ch[tot][0] = ch[tot][1] = 0;
        fa[tot] = p, size[tot] = 1;
        return tot;
    }
}

void recycle(int x){
    if(!x) return;
    recycle(ch[x][0]);
    recycle(ch[x][1]);
    q.push(x);
}

void push_up(int x){
    int l = ch[x][0], r = ch[x][1];
    sum[x] = sum[l] + sum[r] + val[x];
    size[x] = size[l] + size[r] + 1;
    lx[x] = max(lx[l], sum[l] + val[x] + lx[r]);
    rx[x] = max(rx[r], sum[r] + val[x] + rx[l]);
    mx[x] = max(mx[l], mx[r], rx[l] + val[x] + lx[r]);
}

void push_down(int x){
    int l = ch[x][0], r = ch[x][1];
    if(lazy[x]){
        lazy[x] = rev[x] = 0;
        if(l) sum[l] = val[x] * size[l], val[l] = val[x], lazy[l] = 1;
        if(r) sum[r] = val[x] * size[r], val[r] = val[x], lazy[r] = 1;
        if(val[x] >= 0){
            if(l) lx[l] = rx[l] = mx[l] = sum[l];
            if(r) lx[r] = rx[r] = mx[r] = sum[r];
        }
        else{
            if(l) lx[l] = rx[l] = 0, mx[l] = val[x];
            if(r) lx[r] = rx[r] = 0, mx[r] = val[x];
        }
    }
    if(rev[x]){
        rev[x] ^= 1, rev[l] ^= 1, rev[r] ^= 1;
        swap(lx[l], rx[l]), swap(lx[r], rx[r]);
        swap(ch[l][0], ch[l][1]), swap(ch[r][0], ch[r][1]);
    }
}

void rotate(int x){
    int y = fa[x], z = fa[y], p = (ch[y][1] == x) ^ 1;
    push_down(y), push_down(x);
    ch[y][p^1] = ch[x][p], fa[ch[x][p]] = y;
    fa[x] = z, ch[z][ch[z][1] == y] = x, fa[y] = x, ch[x][p] = y;
    push_up(y), push_up(x);
}

void splay(int x, int goal){
    if(x == goal) return;
    while(fa[x] != goal){
        int y = fa[x], z = fa[y];
        if(z != goal){
            if((ch[y][0] == x) ^ (ch[z][0] == y)) rotate(x);
            else rotate(y);
        }
        rotate(x);
    }
    push_up(x);
    if(goal == 0) root = x;
}

int find(int k){
    if(!root) return 0;
    int cur = root, r = size[ch[cur][0]];
    while(1){
        push_down(cur);
        if(r < k){
            k -= r + 1;
            cur = ch[cur][1];
        }
        else{
            if(r > k) cur = ch[cur][0];
            else return cur;
        }
        r = size[ch[cur][0]];
    }
}

int buildTree(int p, int l, int r){
    if(l > r) return 0;
    int mid = (l + r) >> 1;
    int cur = newNode(p, a[mid]);
    ch[cur][0] = buildTree(cur, l, mid - 1);
    ch[cur][1] = buildTree(cur, mid + 1, r);
    push_up(cur);
    return cur;
}

void insert(int pos, int k){
    if(!k) return;
    for(int i = 1; i <= k; i ++) a[i] = read();
    int x = find(pos), y = find(pos + 1);
    splay(x, 0), splay(y, root);
    ch[y][0] = buildTree(y, 1, k);
    push_up(y), push_up(x);
}

void erase(int pos, int k){
    if(!k) return;
    int x = find(pos - 1), y = find(pos + k);
    splay(x, 0), splay(y, root);
    recycle(ch[y][0]);
    ch[y][0] = 0;
    push_up(y), push_up(x);
}

void modify(int pos, int k, int c){
    if(!k) return;
    int x = find(pos - 1), y = find(pos + k);
    splay(x, 0), splay(y, root);
    int key = ch[y][0];
    val[key] = c, sum[key] = size[key] * c, lazy[key] = 1;
    if(val[key] >= 0) mx[key] = lx[key] = rx[key] = sum[key];
    else mx[key] = c, lx[key] = rx[key] = 0;
    push_up(y), push_up(x);
}

void reverse(int pos, int k){
    if(!k) return;
    int x = find(pos - 1), y = find(pos + k);
    splay(x, 0), splay(y, root);
    int key = ch[y][0];
    if(!lazy[key]){
        rev[key] ^= 1;
        swap(lx[key], rx[key]), swap(ch[key][0], ch[key][1]);
        push_up(y), push_up(x);
    }
}

int getSum(int pos, int k){
    if(!k) return 0;
    int x = find(pos - 1), y = find(pos + k);
    splay(x, 0), splay(y, root);
    return sum[ch[y][0]];
}

int getMax(){
    return mx[root];
}

int main(){

    n = read(), m = read();
    mx[0] = -INF;
    root = newNode(0, -INF), ch[root][1] = newNode(root, -INF);
    for(int i = 1; i <= n; i ++) a[i] = read();
    ch[ch[root][1]][0] = buildTree(ch[root][1], 1, n);
    push_up(ch[root][1]), push_up(root);
    while(m --){
        char opt[20]; scanf("%s", opt);
        if(opt[2] == 'X') printf("%d\n", getMax());
        else{
            int pos = read(), tot = read();
            if(opt[0] == 'I') insert(pos, tot);
            else if(opt[0] == 'D') erase(pos, tot);
            else if(opt[0] == 'M') { int c = read(); modify(pos, tot, c); }
            else if(opt[0] == 'R') reverse(pos, tot);
            else if(opt[0] == 'G') printf("%d\n", getSum(pos, tot));
        }
    }
    return 0;
}
posted @ 2019-04-13 02:25  清楚少女ひなこ  阅读(127)  评论(0编辑  收藏  举报