Splay模板

Splay模板

1.区间翻转(洛谷p3391)

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;
typedef long long ll;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x, y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x, y, z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"

const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3f;
const int N = 100005;

int ch[N][2], par[N], val[N], cnt[N], size[N], rev[N], root, ncnt;
int n, m, x, y;

bool chk(int x) {
    return ch[par[x]][1] == x;
}

void pushup(int x) {
    size[x] = size[ch[x][0]] + size[ch[x][1]] + cnt[x];
}

void pushdown(int x) {
    if (rev[x])  {
        swap(ch[x][0], ch[x][1]);
        rev[ch[x][0]] ^= 1;
        rev[ch[x][1]] ^= 1;
        rev[x] = 0;
    }
}

void rotate(int x) {
    int y = par[x], z = par[y], k = chk(x), w = ch[x][k ^ 1];
    ch[y][k] = w; par[w] = y;
    ch[z][chk(y)] = x; par[x] = z;
    ch[x][k ^ 1] = y; par[y] = x;
    pushup(y); pushup(x);
}

void splay(int x, int goal = 0) {
    while (par[x] != goal) {
        int y = par[x], z = par[y];
        if (z != goal) {
            if (chk(x) == chk(y)) rotate(y);
            else rotate(x);
        }
        rotate(x);
    }
    if (!goal) root = x;
}

void insert(int x) {
    int cur = root, p = 0;
    while (cur && val[cur] != x) {
        p = cur;
        cur = ch[cur][x > val[cur]];
    }
    if (cur) {
        cnt[cur]++;
    } else {
        cur = ++ncnt;
        if (p) ch[p][x > val[p]] = cur;
        ch[cur][0] = ch[cur][1] = 0;
        par[cur] = p; val[cur] = x;
        cnt[cur] = size[cur] = 1;
    }
    splay(cur);
}

void find(int x) {
    int cur = root;
    while (ch[cur][x > val[cur]] && val[cur] != x) {
        cur = ch[cur][x > val[cur]];
    }
    splay(cur);
}

int kth(int k) {
    int cur = root;
    while (1) {
        pushdown(cur);
        if (ch[cur][0] && k <= size[ch[cur][0]]) {
            cur = ch[cur][0];
        } else if (k > size[ch[cur][0]] + cnt[cur]) {
            k -= size[ch[cur][0]] + cnt[cur];
            cur = ch[cur][1];
        } else {
            return cur;
        }
    }
}

void reverse(int l, int r) {
    int x = kth(l), y = kth(r + 2);
    splay(x); splay(y, x);
    rev[ch[y][0]] ^= 1;
}

int pre(int x) {
    find(x);
    if (val[root] < x) return root;
    int cur = ch[root][0];
    while (ch[cur][1]) cur = ch[cur][1];
    return cur;
}

int succ(int x) {
    find(x);
    if (val[root] > x) return root;
    int cur = ch[root][1];
    while (ch[cur][0]) cur = ch[cur][0];
    return cur;
}

void output(int x) {
    pushdown(x);
    if (ch[x][0]) output(ch[x][0]);
    if (val[x] && val[x] <= n) printf("%d ", val[x]);
    if (ch[x][1]) output(ch[x][1]);
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 0; i <= n + 1; i++) insert(i);
    while (m--) {
        scanf("%d%d", &x, &y);
        reverse(x, y);
    }
    output(root);
}

2.区间插入,删除,修改,翻转,求和,最最大子列(洛谷P2042)

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;
typedef long long ll;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x, y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x, y, z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"

const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3f;

const int N = 1000016;

int size[N], sum[N], upd[N], rev[N], la[N], ra[N], gss[N];
int val[N], ch[N][2], par[N], ncnt, root;
queue<int> q;

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

inline int newNode(int x) {
    int cur;
    if (q.empty()) cur = ++ncnt;
    else cur = q.front(), q.pop();
    ch[cur][0] = ch[cur][1] = par[cur] = 0;
    val[cur] = sum[cur] = gss[cur] = x;
    la[cur] = ra[cur] = max(0, x);
    upd[cur] = rev[cur] = 0;
    size[cur] = 1;
    return cur;
}

inline bool chk(int x) {
    return ch[par[x]][1] == x;
}

inline void pushup(int x) {
    int l = ch[x][0], r = ch[x][1];
    size[x] = size[l] + size[r] + 1;
    sum[x] = sum[l] + sum[r] + val[x];
    // 这里和线段树不同,线段树只有叶子上有权值,平衡树上所有点都有,必须+val[x] 
    la[x] = max(la[l], sum[l] + val[x] + la[r]);
    ra[x] = max(ra[r], sum[r] + val[x] + ra[l]);
    gss[x] = max(ra[l] + val[x] + la[r], max(gss[l], gss[r]));
}

inline void rotate(int x) {
    int y = par[x], z = par[y], k = chk(x), w = ch[x][k^1];
    ch[y][k] = w; par[w] = y;
    ch[z][chk(y)] = x; par[x] = z;
    ch[x][k^1] = y; par[y] = x;
    pushup(y); pushup(x);
}

inline void pushdown(int x) {
    int l = ch[x][0], r = ch[x][1];
    if (upd[x]) {
        upd[x] = rev[x] = 0;
        if (l) {
            upd[l] = 1; val[l] = val[x];
            sum[l] = val[x] * size[l];
            la[l] = ra[l] = max(sum[l], 0);
            gss[l] = val[x] < 0 ? val[x] : sum[l];
        }
        if (r) {
            upd[r] = 1; val[r] = val[x];
            sum[r] = val[x] * size[r];
            la[r] = ra[r] = max(sum[r], 0);
            gss[r] = val[x] < 0 ? val[x] : sum[r];
        }
    }
    if (rev[x]) {
        rev[l] ^= 1; rev[r] ^= 1; rev[x] = 0;
        swap(la[l], ra[l]); swap(la[r], ra[r]);
        swap(ch[l][0], ch[l][1]);
        swap(ch[r][0], ch[r][1]);
    }
}

inline void splay(int x, int goal = 0) {
    while (par[x] != goal) {
        int y = par[x], z = par[y];
        if (z != goal) {
            if (chk(x) == chk(y)) rotate(y);
            else rotate(x);
        }
        rotate(x);
    }
    if (!goal) root = x;
}

int build(int l, int r, int *arr) {
    if (l > r) return 0;
    int mid = (l+r)>>1, cur = newNode(arr[mid]);
    if (l == r) return cur;
    if ((ch[cur][0] = build(l, mid-1, arr))) par[ch[cur][0]] = cur;
    if ((ch[cur][1] = build(mid+1, r, arr))) par[ch[cur][1]] = cur;
    pushup(cur);
    return cur;
}

inline int kth(int k) {
    int cur = root;
    while (1) {
        pushdown(cur);
        if (ch[cur][0] && k <= size[ch[cur][0]]) {
            cur = ch[cur][0];
        } else if (k > size[ch[cur][0]] + 1) {
            k -= size[ch[cur][0]] + 1;
            cur = ch[cur][1];
        } else {
            return cur;
        }
    }
}

inline void insert(int x, int y) {
    int u = kth(x+1), v = kth(x+2);
    splay(u); splay(v, u);
    ch[v][0] = y; par[y] = v;
    pushup(v); pushup(u); 
}

inline int qsum(int x, int y) {
    int u = kth(x), v = kth(x+y+1);
    splay(u); splay(v, u);
    return sum[ch[v][0]];
}

inline int qgss() {
    return gss[root];
}

inline void remove(int x, int y) {
    int u = kth(x), v = kth(x+y+1);
    splay(u); splay(v, u);
    recycle(ch[v][0]);
    ch[v][0] = 0;
    pushup(v); pushup(u);
}

inline void reverse(int x, int y) {
    int u = kth(x), v = kth(x+y+1);
    splay(u); splay(v, u);
    int w = ch[v][0];
    if (!upd[w]) {
        rev[w] ^= 1;
        swap(ch[w][0], ch[w][1]);
        swap(la[w], ra[w]);
        pushup(v); pushup(u);
    }
}

inline void update(int x, int y, int z) {
    int u = kth(x), v = kth(x+y+1);
    splay(u); splay(v, u);
    int w = ch[v][0];
    upd[w] = 1; val[w] = z; sum[w] = size[w] * z;
    la[w] = ra[w] = max(0, sum[w]);
    gss[w] = z < 0 ? z : sum[w];
    pushup(v); pushup(u);
}

int n, m, arr[N], c, x, y, z;
char buf[32];

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 2; i <= n+1; i++) {
        scanf("%d", arr+i);
    }
    gss[0] = val[0] = 0xcfcfcfcf;
    arr[1] = arr[n += 2] = 0xcfcfcfcf;
    build(1, n, arr); root = 1;
    while (m--) {
        scanf("%s", buf);
        switch ((buf[2] + buf[1]) ^ *buf) {
            case 'G'^('E'+'T'):
                scanf("%d%d", &x, &y);
                printf("%d\n", qsum(x, y));
                break;
            case 'M'^('A'+'X'):
                printf("%d\n", qgss());
                break;
            case 'R'^('E'+'V'):
                scanf("%d%d", &x, &y);
                reverse(x, y);
                break;
            case 'M'^('A'+'K'):
                scanf("%d%d%d", &x, &y, &z);
                update(x, y, z);
                break;
            case 'D'^('E'+'L'):
                scanf("%d%d", &x, &y);
                remove(x, y);
                break;
            case 'I'^('N'+'S'):
                scanf("%d%d", &x, &y);
                memset(arr, 0, sizeof arr);
                for (int i = 1; i <= y; i++) {
                    scanf("%d", arr+i);
                }
                insert(x, build(1, y, arr));
                break;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值