ZOJ2112 Dynamic Rankings 线段树+平衡树

来源:互联网 发布:剑灵男捏脸数据导入图 编辑:程序博客网 时间:2024/06/06 00:02

有修改的区间第K大数

惭愧啊,到现在才做到这道题,这道题公认有两种做法,一种是树状数组+主席树,遗憾地说我不会……

另外一种是线段树套平衡树,我用的是这种方法,只要线段树每一个节点都是一棵平衡树,我们就可以对序列进行动态修改了。

代码上,主代码部分和线段树部分我写的,treap参照了silver__bullet的代码,为防止内存开销过大,采用动态建树,恰好我不会指针……

//BZOJ上面A的……
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int inf = ~0u >> 1;const int N = (int)1e5 + 10;const int maxn = (int)1e9 + 1;#define lson l, m, n << 1#define rson m + 1, r, n << 1 | 1int x[N], n, m;struct Treap{    struct node{        node *ch[2];        int v, p, sz;        node(int _v, node *n):            v(_v){ch[0] = ch[1] = n; p = rand(); sz = 1;}        void update(){sz = ch[0]->sz + ch[1]->sz + 1;}    };    node *root, *null;    Treap(){    }    void init(){        null = new node(0, 0); null->sz = 0; null->p = inf;        null->ch[0] = null->ch[1] = null;        root = null;    }    void rotate(node *&t, bool d){        node *_t = t->ch[d];        t->ch[d] = _t->ch[!d];        _t->ch[!d] = t;        _t->update();        t->update();        t = _t;    }    void __insert(node *&t, int val){        if (t == null){            t = new node(val, null);            return;        }        bool d = val > t->v;        __insert(t->ch[d], val);        if (t->ch[d]->p < t->p) rotate(t, d);        t->update();    }    void __del(node *&t, int val){        if (t == null) return;        if (val == t->v){            bool d = t->ch[1]->p < t->ch[0]->p;            if (t->ch[d] == null){                delete t;                t = null;                return;            }            rotate(t, d);            __del(t->ch[!d], val);        }else{            bool d = val > t->v;            __del(t->ch[d], val);        }        t->update();    }    int __rank(node *t, int val){        if (t == null) return 0;        int num = t->ch[0]->sz;        if (val < t->v) return __rank(t->ch[0], val);        return num + 1 + __rank(t->ch[1], val);    }    void __show(node *x){        if (x == null) return;        __show(x->ch[0]);        printf("%d ", x->v);        __show(x->ch[1]);    }    void insert(int val){        __insert(root, val);    }    void del(int val){        __del(root, val);    }    int rank(int val){        return __rank(root, val);    }    void show(){        __show(root);        puts("");    }    void __fre(node *t){        if (t == null) return;        __fre(t->ch[0]);        __fre(t->ch[1]);        delete t;    }    void fre(){        __fre(root);    }};struct segtree{    Treap s[N << 2];    void build(int l, int r, int n){        s[n].init();        for (int i = l; i <= r; i++)            s[n].insert(x[i]);        if (l == r) return;        int m = (l + r) >> 1;        build(lson);        build(rson);    }    void del(int l, int r, int n){        s[n].fre();        if (l == r) return;        int m = (l + r) >> 1;        del(lson);        del(rson);    }    void update(int nn, int a, int l, int r, int n){        s[n].del(x[nn]);        s[n].insert(a);        if (l == r) return;        int m = (l + r) >> 1;        if (nn <= m) update(nn, a, lson);        else update(nn, a, rson);    }    int query(int ll, int rr, int val, int l, int r, int n){        if (ll == l && rr == r){            return s[n].rank(val);        }        int m = (l + r) >> 1;        if (rr <= m) return query(ll, rr, val, lson);        else if (ll > m) return query(ll, rr, val, rson);        else return query(ll, m, val, lson) + query(m + 1, rr, val, rson);    }};segtree T;int check(int L, int R, int val, int k){    int a = T.query(L, R, val - 1, 1, n, 1);    int b = T.query(L, R, val, 1, n, 1);    if (k > a && k <= b) return 1;    if (k <= a) return 0;    if (k > b) return -1;}int bs(int l, int r, int L, int R, int k){    while(l <= r){        int m = (l + r) >> 1;        int res = check(L, R, m, k);        if (res == 1) return m;        else if (res == -1) l = m + 1;        else r = m - 1;    }}int main(){    #ifndef ONLINE_JUDGE    freopen("in", "rt", stdin);    #endif    scanf("%d%d", &n, &m);    for (int i = 1; i <= n; i++) scanf("%d", &x[i]);    T.build(1, n, 1);    char op[5]; int l, r, k;    while(m--){        scanf("%s", op);        if (op[0] == 'Q'){            scanf("%d%d%d", &l, &r, &k);            int ans = bs(0, maxn, l, r, k);            printf("%d\n", ans);        }else{            scanf("%d%d", &l, &r);            T.update(l, r, 1, n, 1);            x[l] = r;        }    }    T.del(1, n, 1);    return 0;}

 

原创粉丝点击