Splay 区间信息的维护与查询 静态模板

来源:互联网 发布:网络语言我都快长草了 编辑:程序博客网 时间:2024/05/17 04:08

Splay树除了被用作平衡二叉树之外,还有许多更高级但我们不常用的功能,比如:用Splay的旋转操作来维护区间信息,这里的旋转优先级我们可以用一个Rank来表示,则Rank[i]就代表了第i个点的优先级(对应的就是原来的序列中的位置标号),通过依据对位置标号的旋转操作,我们可以更加方便直观的维护一个区间的总和、最值等信息,并且理论复杂度与线段树相当。

#include<iostream>#include<cstring>#include<cstdio>using namespace std;const int maxn = 2000 + 10;const int INF = 0x3f3f3f3f;struct SplayTree {    int n, root;    int c[maxn][2], fa[maxn], tid[maxn];    int Val[maxn], Max[maxn], Rank[maxn], size[maxn];    void init() {         n = root = 0;        memset(c, 0, sizeof(c));         memset(fa, 0, sizeof(fa));        memset(tid, 0, sizeof(tid));        memset(Rank, 0, sizeof(Rank));    }    int Newnode(int val, int k) {        ++n;         Val[n] = Max[n] = val;         Rank[n] = k; size[n] = 1; tid[k] = n;        return n;    }    void Push_up(int u) {        Max[u] = Val[u];        if(c[u][0]) Max[u] = max(Max[u], Max[c[u][0]]);        if(c[u][1]) Max[u] = max(Max[u], Max[c[u][1]]);        size[u] = size[c[u][0]] + size[c[u][1]] + 1;    }    void rotate(int u) {        int v = fa[u], w = fa[v], t = c[v][1] == u;        fa[c[u][t^1]] = v, c[v][t] = c[u][t^1];         c[u][t^1] = v; fa[u] = w; fa[v] = u;         if(root == v) root = u;         else c[w][c[w][1] == v] = u;        Push_up(v);    }    void Splay(int u, int pos) {        while(fa[u] != pos) {            int v = fa[u], w = fa[v];            if(fa[v] == pos)                 rotate(u);            else if((c[v][0] == u) == (c[w][0] == v))                  rotate(v), rotate(u);            else                 rotate(u), rotate(u);            Push_up(u);        }    }    void join(int u, int k, int val) {        int d = k >= Rank[u];        c[u][d] = Newnode(val, k); fa[n] = u;        int t = n;        while(t) {            Push_up(t);            t = fa[t];        }        Splay(n, 0);    }    void insert(int k, int val, int u) {        int d = k >= Rank[u];        if(c[u][d])             insert(k, val, c[u][d]);        else join(u, k, val);    }    void update(int k, int val, int u) {        if(Rank[u] == k) {            Val[u] = val;            Push_up(u);            return;        }        int d = k >= Rank[u];        if(c[u][d])             update(k, val, c[u][d]);        Push_up(u);    }    int query(int x, int y) {        Splay(tid[x-1], 0);        Splay(tid[y+1], root);        return Max[c[tid[y+1]][0]];    }}SPT[maxn], test;char s[20];int n, m;int x, y, z, x1, y1, x2, y2;int main() {#ifndef ONLINE_JUDGE    freopen("yolk.in", "r", stdin);    freopen("yolk.out", "w", stdout);#endif    /*test.init();    test.root = test.Newnode(-INF, 0);    test.insert(1, 999, test.root);    test.insert(2, 0, test.root);    test.insert(3, -5, test.root);    test.insert(4, -INF, test.root);    cout << test.query(1, 3) << endl;*/    scanf("%d%d", &n, &m);    for(int i=1; i<=n; i++) {        SPT[i].init();        SPT[i].root = SPT[i].Newnode(-INF, 0);        for(int j=1; j<=n; j++)            SPT[i].insert(j, 0, SPT[i].root);        SPT[i].insert(n+1, -INF, SPT[i].root);    }    while(m--) {        scanf("%s", s);        if(s[0] == 'C') {            scanf("%d%d%d", &x, &y, &z);            SPT[x].update(y, z, SPT[x].root);        }else {            int ans = 0;            scanf("%d%d%d%d", &x1, &y1, &x2, &y2);            for(int i=x1; i<=x2; i++) ans = max(ans, SPT[i].query(y1, y2));            cout << ans << endl;        }    }    return 0;}
0 0
原创粉丝点击